From 694d8ceed5c885b6ed51f8872a9514fd6e3ba837 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 9 Jan 2024 18:44:35 +0530 Subject: [PATCH 1/2] Subfunctions for mode_switch_decoder_LPD converted to fixed point. [x] Fixed point changes added to core_com_config.c. [x] init_tcx_cfg, TonalMDCTconceal_Init modified with fixed changes. --- Workspace_msvc/lib_com.vcxproj | 1 + Workspace_msvc/lib_com.vcxproj.filters | 1 + lib_com/cldfb.c | 29 +- lib_com/core_com_config.c | 692 ++++++++++++++++++++++--- lib_com/float_to_fix_ops.c | 76 +++ lib_com/ivas_prot.h | 4 +- lib_com/ivas_stereo_psychlpc_com.c | 40 +- lib_com/prot_fx2.h | 121 ++++- lib_com/stat_com.h | 1 + lib_com/tcx_mdct_window.c | 8 +- lib_com/tcx_utils_fx.c | 4 +- lib_com/tools_fx.c | 27 + lib_dec/amr_wb_dec_fx.c | 2 +- lib_dec/core_dec_init.c | 200 ++++++- lib_dec/core_dec_init_fx.c | 80 ++- lib_dec/core_dec_reconf_fx.c | 2 +- lib_dec/core_dec_switch_fx.c | 4 +- lib_dec/decision_matrix_dec_fx.c | 2 +- lib_dec/evs_dec_fx.c | 2 +- lib_dec/fd_cng_dec_fx.c | 2 +- lib_dec/ivas_mdct_core_dec.c | 8 +- lib_dec/stat_dec.h | 15 +- lib_dec/tonalMDCTconcealment.c | 42 +- lib_dec/tonalMDCTconcealment_fx.c | 128 ++++- 24 files changed, 1305 insertions(+), 186 deletions(-) create mode 100644 lib_com/float_to_fix_ops.c diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 9829e097b..de047134c 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -188,6 +188,7 @@ + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 7a4bb01d8..34135d661 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -805,6 +805,7 @@ common_ivas_c + diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 14fcff48a..b77c38d3b 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -42,7 +42,7 @@ #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" - +#include "prot_fx2.h" #if __STDC_VERSION__ >= 199901L #if defined __ICL #define restrict __restrict @@ -723,6 +723,12 @@ ivas_error openCldfb_ivas( { buf_len = hs->p_filter_length; } +#ifdef IVAS_FLOAT_FIXED + if ( ( hs->cldfb_state_fx = (Word16 *) malloc( buf_len * sizeof( Word16 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); + } +#endif // IVAS_FLOAT_FIXED if ( ( hs->cldfb_state = (float *) malloc( buf_len * sizeof( float ) ) ) == NULL ) { @@ -1230,3 +1236,24 @@ void cldfb_reset_memory_ivas( return; } +void cldfb_reset_memory_fx( + HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */, + Word16* memory_length +) +{ + UWord16 offset = sub(hs->p_filter_length, hs->no_channels); + + IF (hs->type == CLDFB_ANALYSIS) + { + *memory_length = offset; + } + ELSE + { + *memory_length = hs->p_filter_length; + } + + /* save the memory */ + set16_fx(hs->cldfb_state_fx, 0, *memory_length); + + return; +} \ No newline at end of file diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index 6b7fe1680..d490b44b4 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -41,7 +41,7 @@ #include "prot.h" #include "wmc_auto.h" #include "ivas_prot.h" - +#include "prot_fx2.h" /*-------------------------------------------------------------------* * is_EVS_bitrate() @@ -50,23 +50,23 @@ *-------------------------------------------------------------------*/ /*! r: flag indicating a valid bitrate */ -int16_t is_EVS_bitrate( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - int16_t *Opt_AMR_WB /* i : AMR-WB IO flag */ +Word16 is_EVS_bitrate( + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + Word16 *Opt_AMR_WB /* i : AMR-WB IO flag */ ) { - int16_t j; + Word16 j; j = 0; - while ( j < SIZE_BRATE_TBL && ivas_total_brate != brate_tbl[j] ) + WHILE ( LT_16(j , SIZE_BRATE_TBL) && NE_32(ivas_total_brate , brate_tbl[j]) ) { j++; } /* AMR-WB IO mode/EVS primary mode determination */ - if ( j >= SIZE_BRATE_TBL ) + IF ( GE_16(j , SIZE_BRATE_TBL )) { - switch ( ivas_total_brate ) + SWITCH ( ivas_total_brate ) { case ACELP_6k60: case ACELP_8k85: @@ -77,17 +77,17 @@ int16_t is_EVS_bitrate( case ACELP_19k85: case ACELP_23k05: case ACELP_23k85: - break; + BREAK; default: { return 0; } - break; + BREAK; } *Opt_AMR_WB = 1; } - else + ELSE { *Opt_AMR_WB = 0; } @@ -103,50 +103,50 @@ int16_t is_EVS_bitrate( *-------------------------------------------------------------------*/ /*! r: codec mode */ -int16_t get_codec_mode( - const int32_t total_brate /* i : total bitrate */ +Word16 get_codec_mode( + const Word32 total_brate /* i : total bitrate */ ) { - int16_t codec_mode = -1; + Word16 codec_mode = -1; - switch ( total_brate ) + SWITCH ( total_brate ) { case 5900: codec_mode = MODE1; - break; + BREAK; case 7200: codec_mode = MODE1; - break; + BREAK; case 8000: codec_mode = MODE1; - break; + BREAK; case 9600: codec_mode = MODE2; - break; + BREAK; case 13200: codec_mode = MODE1; - break; + BREAK; case 16400: codec_mode = MODE2; - break; + BREAK; case 24400: codec_mode = MODE2; - break; + BREAK; case 32000: codec_mode = MODE1; - break; + BREAK; case 48000: codec_mode = MODE2; - break; + BREAK; case 64000: codec_mode = MODE1; - break; + BREAK; case 96000: codec_mode = MODE2; - break; + BREAK; case 128000: codec_mode = MODE2; - break; + BREAK; } return codec_mode; @@ -272,23 +272,86 @@ Word16 getTcxonly( return tcxonly; } +Word16 getTcxonly_fx( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + const Word16 is_ism_format /* i : flag indicating ISM format */ +) +{ + Word16 tcxonly = 0; + + SWITCH( element_mode ) + { + case EVS_MONO: + IF( GT_32( total_brate, ACELP_32k ) ) + { + tcxonly = 1; + } + BREAK; + case IVAS_SCE: + IF( is_ism_format ) + { + IF( GT_32( total_brate, MAX_ACELP_BRATE_ISM ) ) + { + tcxonly = 1; + } + } + ELSE + { + IF( GT_32( total_brate, MAX_ACELP_BRATE ) ) + { + tcxonly = 1; + } + } + BREAK; + + case IVAS_CPE_DFT: + case IVAS_CPE_TD: + IF( GT_32( total_brate, MAX_ACELP_BRATE ) ) + { + tcxonly = 1; + } + BREAK; + case IVAS_CPE_MDCT: + IF( GE_32( total_brate, ( MCT_flag ? IVAS_32k : IVAS_48k ) ) ) + { + tcxonly = 1; + } + BREAK; + } + + return tcxonly; +} + /*-------------------------------------------------------------------* * getCtxHm() * * *-------------------------------------------------------------------*/ -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 */ +Word16 getCtxHm( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 rf_flag /* i : flag to signal the RF mode */ ) { - int16_t ctx_hm = 0; + Word16 ctx_hm; - if ( ( ( element_mode <= IVAS_SCE && total_brate > LPC_SHAPED_ARI_MAX_RATE ) || ( element_mode > IVAS_SCE && total_brate > LPC_SHAPED_ARI_MAX_RATE_CPE ) ) && !rf_flag && ( ( total_brate <= IVAS_64k && element_mode != IVAS_CPE_DFT ) || ( total_brate < 24400 && element_mode == IVAS_CPE_DFT ) ) && element_mode != IVAS_CPE_MDCT ) + ctx_hm = 0; + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + if ( ( ( LE_16( element_mode, IVAS_SCE ) && GT_32( total_brate, LPC_SHAPED_ARI_MAX_RATE ) ) || ( GT_16( element_mode, IVAS_SCE ) && GT_32( total_brate, LPC_SHAPED_ARI_MAX_RATE_CPE ) ) ) && !rf_flag && ( ( LE_32( total_brate, IVAS_64k ) && NE_16( element_mode, IVAS_CPE_DFT ) ) || ( LT_32( total_brate, 24400 ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) { ctx_hm = 1; + move16(); } return ctx_hm; @@ -300,15 +363,18 @@ int16_t getCtxHm( * *-------------------------------------------------------------------*/ -int16_t getResq( - const int32_t total_brate /* i : total bitrate */ +Word16 getResq( + const Word32 total_brate /* i : total bitrate */ ) { - int16_t resq = 0; + Word16 resq; - if ( total_brate <= IVAS_64k ) + resq = 0; + move16(); + IF ( LE_32( total_brate, IVAS_64k ) ) { resq = 1; + move16(); } return resq; @@ -320,24 +386,31 @@ int16_t getResq( * *-------------------------------------------------------------------*/ -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 */ +Word16 getTnsAllowed( + const Word32 total_brate, /* i : total bitrate */ + const Word16 igf, /* i : flag indicating IGF activity*/ + const Word16 element_mode /* i : IVAS element mode */ ) { - int16_t tnsAllowed = 0; + Word16 tnsAllowed = 0; - if ( igf ) + tnsAllowed = 0; + move16(); + IF( NE_16(igf , 0) ) { - if ( total_brate > HQ_16k40 || ( ( total_brate > HQ_13k20 ) && element_mode == IVAS_CPE_DFT ) ) + IF( GT_32( total_brate, HQ_16k40 ) || ( GT_32( total_brate, HQ_13k20 ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) ) { tnsAllowed = 1; + move16(); } } - else if ( total_brate > HQ_32k ) + ELSE { - tnsAllowed = 1; + IF( GT_32( total_brate, HQ_32k ) ) + { + tnsAllowed = 1; + move16(); + } } return tnsAllowed; @@ -349,23 +422,23 @@ int16_t getTnsAllowed( * *-------------------------------------------------------------------*/ -int16_t getRestrictedMode( - const int16_t element_mode, /* i : IVAS element mode */ - const int32_t total_brate, /* i : total bitrate */ - const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ +Word16 getRestrictedMode( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ ) { - int16_t restrictedMode = 3; + Word16 restrictedMode = 3; - if ( !Opt_AMR_WB && ( total_brate > HQ_32k && element_mode != IVAS_SCE ) ) + IF ( !Opt_AMR_WB && ( GT_32(total_brate , HQ_32k) && NE_16(element_mode , IVAS_SCE) ) ) { restrictedMode = 6; } - else if ( !Opt_AMR_WB && ( total_brate > HQ_48k && element_mode == IVAS_SCE ) ) + ELSE IF ( !Opt_AMR_WB && ( GT_32(total_brate , HQ_48k) && EQ_16(element_mode , IVAS_SCE) ) ) { restrictedMode = 6; } - else if ( Opt_AMR_WB ) + ELSE IF ( Opt_AMR_WB ) { restrictedMode = 1; } @@ -388,6 +461,16 @@ int16_t getMdctWindowLength( return mdctWindowLength; } +#ifdef IVAS_FLOAT_FIXED +Word16 getMdctWindowLength_fx( + const Word16 fscale ) +{ + Word16 mdctWindowLength; + mdctWindowLength = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscale ), LD_FSCALE_DENOM ) ); + + return mdctWindowLength; +} +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * sr2fscale() @@ -403,6 +486,51 @@ int16_t sr2fscale( return (int16_t) ( ( FSCALE_DENOM * sr_core ) / 12800 ); } +Word16 sr2fscale_fx( + const Word32 sr_core /* i : internal sampling rate */ +) +{ + Word16 fscale; + + SWITCH( sr_core ) + { + case 8000: + fscale = ( FSCALE_DENOM * 8000 ) / 12800; + move16(); + BREAK; + + case 12800: + fscale = FSCALE_DENOM; + move16(); + BREAK; + + case 16000: + fscale = ( FSCALE_DENOM * 16000 ) / 12800; + move16(); + BREAK; + + case 25600: + fscale = ( FSCALE_DENOM * 25600 ) / 12800; + move16(); + BREAK; + + case 32000: + fscale = ( FSCALE_DENOM * 32000 ) / 12800; + move16(); + BREAK; + + case 48000: + fscale = ( FSCALE_DENOM * 48000 ) / 12800; + move16(); + BREAK; + + default: + assert( 0 ); + fscale = 0; /* just to avoid compiler warning */ + BREAK; + } + return fscale; +} /*-------------------------------------------------------------------* * getCoreSamplerateMode2_flt() * @@ -509,7 +637,7 @@ Word32 getCoreSamplerateMode2( { sr_core = INT_FS_16k; } - else if (bwd_swb_or_fb_flag && LE_32(total_brate, MAX_ACELP_BRATE) && EQ_16(element_mode, IVAS_SCE) && is_ism_format) + ELSE IF (bwd_swb_or_fb_flag && LE_32(total_brate, MAX_ACELP_BRATE) && EQ_16(element_mode, IVAS_SCE) && is_ism_format) { sr_core = 25600; } @@ -669,6 +797,108 @@ int16_t getIgfPresent( return igfPresent; } +Word16 getIgfPresent_fx( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +) +{ + Word16 igfPresent = 0; + move16(); + + IF( EQ_16( bwidth, SWB ) ) + { + SWITCH( element_mode ) + { + case EVS_MONO: + case IVAS_SCE: + IF( LE_32( total_brate, HQ_64k ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + case IVAS_CPE_DFT: + case IVAS_CPE_TD: + IF( LE_32( total_brate, HQ_48k ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + case IVAS_CPE_MDCT: + IF( LE_32( total_brate, IVAS_96k ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + } + } + ELSE IF( EQ_16( bwidth, FB ) ) + { + SWITCH( element_mode ) + { + case EVS_MONO: + case IVAS_SCE: + IF( LE_32( total_brate, IVAS_128k ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + case IVAS_CPE_DFT: + case IVAS_CPE_TD: + IF( LE_32( total_brate, IVAS_48k ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + case IVAS_CPE_MDCT: + IF( LE_32( total_brate, IVAS_128k ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + } + } + ELSE IF( bwidth == WB ) + { + SWITCH ( element_mode ) + { + case EVS_MONO: + case IVAS_SCE: + IF( LE_32( total_brate, ACELP_9k60 ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + case IVAS_CPE_DFT: + case IVAS_CPE_TD: + case IVAS_CPE_MDCT: + IF ( LE_32( total_brate, ACELP_13k20 ) ) + { + igfPresent = 1; + move16(); + } + BREAK; + } + } + test(); + test(); + test(); + IF ( ( ( EQ_16( bwidth, WB ) ) || ( EQ_16( bwidth, SWB ) ) ) && ( EQ_16( rf_mode, 1 ) ) && ( EQ_32( total_brate, ACELP_13k20 ) ) ) + { + igfPresent = 1; + move16(); + } + + return igfPresent; +} /*-------------------------------------------------------------------* * getCnaPresent() * @@ -709,21 +939,51 @@ int16_t getCnaPresent( return flag_cna; } +Word16 getCnaPresent_fx( + const Word16 element_mode, /* i : element mode */ + const Word32 element_brate, /* i : element bitrate */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 bwidth /* i : audio bandwidth */ +) +{ + Word16 flag_cna = 0; + + IF( EQ_16( element_mode, IVAS_CPE_DFT ) && LE_32( element_brate, CNA_MAX_BRATE_DFT_STEREO ) ) + { + flag_cna = 1; + } + ELSE + { + move16(); + test(); + IF ( LE_16( bwidth, SWB ) && ( LE_32( total_brate, ACELP_13k20 ) ) ) + { + flag_cna = 1; + move16(); + } + } + + return flag_cna; +} /*-------------------------------------------------------------------* * getTcxLtp() * * *-------------------------------------------------------------------*/ -int16_t getTcxLtp( - const int32_t sr_core /* i : internal sampling rate */ +Word16 getTcxLtp( + const Word32 sr_core /* i : internal sampling rate */ ) { - int16_t tcxltp = 0; + Word16 tcxltp = 0; - if ( sr_core <= 25600 ) + tcxltp = 0; + move16(); + test(); + IF( ( LE_32( sr_core, 25600 ) ) ) { tcxltp = 1; + move16(); } return tcxltp; @@ -735,51 +995,75 @@ int16_t getTcxLtp( * *-------------------------------------------------------------------*/ -int16_t initPitchLagParameters( - const int32_t sr_core, - int16_t *pit_min, - int16_t *pit_fr1, - int16_t *pit_fr1b, - int16_t *pit_fr2, - int16_t *pit_max ) +Word16 initPitchLagParameters( + const Word32 sr_core, + Word16 *pit_min, + Word16 *pit_fr1, + Word16 *pit_fr1b, + Word16 *pit_fr2, + Word16 *pit_max ) { - int16_t pit_res_max; + Word16 pit_res_max; - if ( sr_core == INT_FS_12k8 ) + IF( EQ_32( sr_core, INT_FS_12k8 ) ) { *pit_min = PIT_MIN_12k8; + move16(); *pit_max = PIT_MAX_12k8; + move16(); *pit_fr2 = PIT_FR2_12k8; + move16(); *pit_fr1 = PIT_FR1_12k8; + move16(); *pit_fr1b = PIT_FR1_8b_12k8; + move16(); pit_res_max = 4; + move16(); } - else if ( sr_core == INT_FS_16k ) + ELSE IF( EQ_32( sr_core, INT_FS_16k ) ) { *pit_min = PIT_MIN_16k; + move16(); *pit_max = PIT16k_MAX; + move16(); *pit_fr2 = PIT_FR2_16k; + move16(); *pit_fr1 = PIT_FR1_16k; + move16(); *pit_fr1b = PIT_FR1_8b_16k; + move16(); pit_res_max = 6; + move16(); } - else if ( sr_core == 25600 ) + ELSE IF( EQ_32(sr_core , 25600) ) { *pit_min = PIT_MIN_25k6; + move16(); *pit_max = PIT_MAX_25k6; + move16(); *pit_fr2 = PIT_FR2_25k6; + move16(); *pit_fr1 = PIT_FR1_25k6; + move16(); *pit_fr1b = PIT_FR1_8b_25k6; + move16(); pit_res_max = 4; + move16(); } - else /* sr_core==32000 */ + ELSE /* sr_core==32000 */ { *pit_min = PIT_MIN_32k; + move16(); *pit_max = PIT_MAX_32k; + move16(); *pit_fr2 = PIT_FR2_32k; + move16(); *pit_fr1 = PIT_FR1_32k; + move16(); *pit_fr1b = PIT_FR1_8b_32k; + move16(); pit_res_max = 6; + move16(); } return pit_res_max; @@ -791,29 +1075,32 @@ int16_t initPitchLagParameters( * *-------------------------------------------------------------------*/ -int16_t getNumTcxCodedLines( - const int16_t bwidth /* i : audio bandwidth */ +Word16 getNumTcxCodedLines( + const Word16 bwidth /* i : audio bandwidth */ ) { - int16_t tcx_coded_lines; + Word16 tcx_coded_lines; + + tcx_coded_lines = 0; + move16(); - switch ( bwidth ) + SWITCH( bwidth ) { case NB: tcx_coded_lines = 160; - break; + BREAK; case WB: tcx_coded_lines = 320; - break; + BREAK; case SWB: tcx_coded_lines = 640; - break; + BREAK; case FB: tcx_coded_lines = 960; - break; + BREAK; default: tcx_coded_lines = 0; - break; + BREAK; } return tcx_coded_lines; @@ -825,17 +1112,22 @@ int16_t getNumTcxCodedLines( * *-------------------------------------------------------------------*/ -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 */ +Word16 getTcxLpcShapedAri( + const Word32 total_brate, /* i : total bitrate */ + const Word16 rf_mode, /* i : flag to signal the RF mode */ + const Word16 element_mode /* i : IVAS element mode */ ) { - int16_t tcx_lpc_shaped_ari = 0; + Word16 tcx_lpc_shaped_ari = 0; - if ( ( ( element_mode <= IVAS_SCE && total_brate <= LPC_SHAPED_ARI_MAX_RATE ) || ( element_mode > IVAS_SCE && total_brate <= LPC_SHAPED_ARI_MAX_RATE_CPE ) ) || rf_mode ) + move16(); + test(); + test(); + test(); + IF( ( ( LE_16( element_mode, IVAS_SCE ) && LE_32( total_brate, LPC_SHAPED_ARI_MAX_RATE ) ) || ( GT_16( element_mode, IVAS_SCE ) && LE_32( total_brate, LPC_SHAPED_ARI_MAX_RATE_CPE ) ) ) || rf_mode ) { tcx_lpc_shaped_ari = 1; + move16(); } return tcx_lpc_shaped_ari; @@ -1072,3 +1364,231 @@ void init_tcx_cfg( return; } +#ifdef IVAS_FLOAT_FIXED +void init_tcx_window_cfg_fx( + TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX Config handle */ + const Word32 sr_core, /* i : SR core */ + const Word32 input_Fs, /* i : input/output SR */ + const Word16 L_frame, /* i : L_frame at sr_core */ + const Word16 L_frameTCX, /* i : L_frame at i/o SR */ + const Word16 encoderLookahead_enc, /* i : encoder LA at sr_core */ + const Word16 encoderLookahead_FB, /* i : encoder LA at i/o SR */ + const Word16 mdctWindowLength, /* i : window length at sr_core */ + const Word16 mdctWindowLengthFB, /* i : window length at i/o SR */ + const Word16 element_mode /* i : mode of CPE/SCE */ +) +{ + /* Symmetric window = sine LD window*/ + hTcxCfg->tcx_mdct_window_delay = mdctWindowLength; + hTcxCfg->tcx_mdct_window_delayFB = mdctWindowLengthFB; + hTcxCfg->tcx_mdct_window_length = mdctWindowLength; + hTcxCfg->tcx_mdct_window_lengthFB = mdctWindowLengthFB; + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window, sr_core, hTcxCfg->tcx_mdct_window_length, FULL_OVERLAP, element_mode ); + + IF( EQ_16( hTcxCfg->tcx_mdct_window_length, hTcxCfg->tcx_mdct_window_lengthFB ) ) + { + Copy_pword( hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_length / 2 ); + } + ELSE + { + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_windowFB, input_Fs, hTcxCfg->tcx_mdct_window_lengthFB, FULL_OVERLAP, element_mode ); + } + + /*ALDO windows for MODE2*/ + mdct_window_aldo( hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame ); + mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, NS2SA_fx2( input_Fs, FRAME_SIZE_NS ) ); + + /*1.25ms transition window for ACELP->TCX*/ + hTcxCfg->tcx_mdct_window_trans_length = NS2SA_fx2( sr_core, ACELP_TCX_TRANS_NS ); + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window_trans, sr_core, hTcxCfg->tcx_mdct_window_trans_length, TRANSITION_OVERLAP, element_mode ); + hTcxCfg->tcx_mdct_window_trans_lengthFB = NS2SA_fx2( input_Fs, ACELP_TCX_TRANS_NS ); + IF( EQ_16( hTcxCfg->tcx_mdct_window_trans_length, hTcxCfg->tcx_mdct_window_trans_lengthFB ) ) + { + Copy_pword( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_length / 2 ); + } + ELSE + { + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window_transFB, input_Fs, hTcxCfg->tcx_mdct_window_trans_lengthFB, TRANSITION_OVERLAP, element_mode ); + } + /*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 ) ); + 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 ) ); + assert( GT_16( hTcxCfg->tcx_mdct_window_half_length, 16 ) && "Half window can not be large enough!" ); + + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window_half, sr_core, hTcxCfg->tcx_mdct_window_half_length, HALF_OVERLAP, element_mode ); + IF( EQ_16( hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_half_lengthFB ) ) + { + Copy_pword( hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_length / 2 ); + } + ELSE + { + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window_halfFB, input_Fs, hTcxCfg->tcx_mdct_window_half_lengthFB, HALF_OVERLAP, element_mode ); + } + + /* minimum overlap 1.25 ms */ + hTcxCfg->tcx_mdct_window_min_length = shr( L_frame, 4 ); /* 1.25ms */ + hTcxCfg->tcx_mdct_window_min_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms */ + /* save complexity by copying the small windows if they have the same length */ + IF( EQ_16( hTcxCfg->tcx_mdct_window_min_length, hTcxCfg->tcx_mdct_window_trans_length ) ) + { + Copy_pword( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length / 2 ); + } + ELSE + { + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window_minimum, sr_core, hTcxCfg->tcx_mdct_window_min_length, MIN_OVERLAP, element_mode ); + } + + IF( EQ_16( hTcxCfg->tcx_mdct_window_min_lengthFB, hTcxCfg->tcx_mdct_window_trans_lengthFB ) ) + { + Copy_pword( hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB / 2 ); + } + ELSE IF( EQ_16( hTcxCfg->tcx_mdct_window_min_length, hTcxCfg->tcx_mdct_window_min_lengthFB ) ) + { + Copy_pword( hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB / 2 ); + } + ELSE + { + mdct_window_sine_IVAS_updated( hTcxCfg->tcx_mdct_window_minimumFB, input_Fs, hTcxCfg->tcx_mdct_window_min_lengthFB, MIN_OVERLAP, element_mode ); + } + /* TCX Offset */ + hTcxCfg->tcx_offset = shr( hTcxCfg->tcx_mdct_window_delay, 1 ); + hTcxCfg->tcx_offsetFB = shr( hTcxCfg->tcx_mdct_window_delayFB, 1 ); + /*<0 rectangular transition with optimized window size = L_frame+L_frame/4*/ + hTcxCfg->lfacNext = sub( hTcxCfg->tcx_offset, shr( L_frame, 2 ) ); + hTcxCfg->lfacNextFB = sub( hTcxCfg->tcx_offsetFB, shr( L_frameTCX, 2 ) ); + + return; +} + +void init_tcx_cfg_fx( + TCX_CONFIG_HANDLE hTcxCfg, + const Word32 total_brate, + const Word32 sr_core, + const Word32 input_Fs, + const Word16 L_frame, + const Word16 bwidth, + const Word16 L_frameTCX, + const Word16 fscale, + const Word16 encoderLookahead_enc, + const Word16 encoderLookahead_FB, + const Word16 preemph_fac, + const Word16 tcxonly, + const Word16 rf_mode, + const Word16 igf, + const Word16 infoIGFStopFreq, + const Word16 element_mode, + const Word16 ini_frame, + const Word16 MCT_flag, + const Word16 fscaleFB) +{ + Word16 i; + Word16 mdctWindowLength; + Word16 mdctWindowLengthFB; + Word16 na_scale_bwidth; + + hTcxCfg->preemph_fac = preemph_fac; + move16(); + + hTcxCfg->tcx5Size = shr( L_frame, 2 ); /* Always 5 ms */ + hTcxCfg->tcx5SizeFB = shr( L_frameTCX, 2 ); /* Always 5 ms */ + + hTcxCfg->tcx_mdct_window_length_old = hTcxCfg->tcx_mdct_window_length; + move16(); + mdctWindowLength = getMdctWindowLength_fx( fscale ); + mdctWindowLengthFB = getMdctWindowLength_fx(fscaleFB); + init_tcx_window_cfg_fx( hTcxCfg, sr_core, input_Fs, L_frame, L_frameTCX, encoderLookahead_enc, encoderLookahead_FB, mdctWindowLength, mdctWindowLengthFB, element_mode ); + /* SQ deadzone & memory quantization*/ + hTcxCfg->sq_rounding = 12288 /*0.375f Q15*/; /*deadzone of 1.25->rounding=1-1.25/2 (No deadzone=0.5)*/ + move16(); + + /* TCX rate loop */ + hTcxCfg->tcxRateLoopOpt = 0; + move16(); + + IF( tcxonly != 0 ) + { + hTcxCfg->tcxRateLoopOpt = 2; + move16(); + } + IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) + hTcxCfg->tcxRateLoopOpt = 3; + hTcxCfg->bandwidth = getTcxBandwidth( bwidth ); + move16(); + + /* set number of coded lines */ + hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( bwidth ); + + /* TNS in TCX */ + hTcxCfg->pCurrentTnsConfig = NULL; + hTcxCfg->fIsTNSAllowed = getTnsAllowed( total_brate, igf, element_mode ); + + IF( hTcxCfg->fIsTNSAllowed ) + { + InitTnsConfigs( bwidth, hTcxCfg->tcx_coded_lines, hTcxCfg->tnsConfig, infoIGFStopFreq, total_brate, element_mode, MCT_flag ); + + SetAllowTnsOnWhite( hTcxCfg->tnsConfig, element_mode == IVAS_CPE_MDCT ); + } + + IF( ini_frame == 0 ) + { + hTcxCfg->tcx_curr_overlap_mode = hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + hTcxCfg->last_aldo = 1; + } + + /* Context HM*/ + hTcxCfg->ctx_hm = getCtxHm( element_mode, total_brate, rf_mode ); + + /* Residual Coding*/ + hTcxCfg->resq = getResq( total_brate ); + IF( hTcxCfg->resq && !tcxonly ) + { + hTcxCfg->tcxRateLoopOpt = 1; + move16(); + } + + /*Set bandwidth scale*/ + IF( EQ_16( bwidth, NB ) ) + { + na_scale_bwidth = NB; + } + ELSE IF( LE_32( sr_core, INT_FS_16k ) ) + { + na_scale_bwidth = WB; + } + ELSE + { + na_scale_bwidth = SWB; + } + hTcxCfg->na_scale = 32767 /*1.0f Q15*/; + + IF( LT_16( na_scale_bwidth, SWB ) && !tcxonly ) + { + FOR( i = 0; i < SIZE_SCALE_TABLE_TCX; i++ ) + { + IF( ( EQ_16( na_scale_bwidth, scaleTcxTable[i].bwmode ) ) && + ( GE_32( total_brate, scaleTcxTable[i].bitrateFrom ) ) && + ( LT_32( total_brate, scaleTcxTable[i].bitrateTo ) ) ) + { + IF( rf_mode ) + { + i--; + } + hTcxCfg->na_scale = scaleTcxTable[i].scale; + BREAK; + } + } + } + + IF( tcxonly ) + { + InitPsychLPC( sr_core, L_frame, hTcxCfg ); + } + ELSE + { + hTcxCfg->psychParamsCurrent = NULL; + } + + return; +} +#endif // IVAS_FLOAT_FIXED diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c new file mode 100644 index 000000000..c2a5ee0b1 --- /dev/null +++ b/lib_com/float_to_fix_ops.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include "options.h" +#include "prot.h" +Word32 floatToFixed(const float f, Word16 Q) +{ + if (Q < 0) + return (Word32)((float)(f) / (float)(1 << (-Q)) + (f >= 0 ? 0.5 : -0.5)); + else + return (Word32)(f * (float)(1 << Q) + (f >= 0 ? 0.5 : -0.5)); +} + +float fixedToFloat(const Word32 i, Word16 Q) +{ + if (Q < 0) + return (i * (float)(1 << (-Q))); + else + return (float)(i) / (float)(1 << Q); +} +void floatToFixed_arrL(const float *f, Word32 *i, Word16 Q, Word16 l) +{ + for (int j = 0; j < l; j++) + { + i[j] = floatToFixed(f[j], Q); + } +} +void floatToFixed_arr(const float *f, Word16 *i, Word16 Q, Word16 l) +{ + for (int j = 0; j < l; j++) + { + i[j] = (Word16)floatToFixed(f[j], Q); + } +} +void fixedToFloat_arrL(const Word32 *i, float *f, Word16 Q, Word16 l) +{ + for (int j = 0; j < l; j++) + { + f[j] = fixedToFloat(i[j], Q); + } +} +void fixedToFloat_arr(const Word16 *i, float *f, Word16 Q, Word16 l) +{ + for (int j = 0; j < l; j++) + { + f[j] = fixedToFloat(i[j], Q); + } +} +Word16 Q_factor(Word16 x) +{ + return norm_s(x); +} +Word16 Q_factor_L(Word32 x) +{ + return norm_l(x); +} +Word16 Q_factor_arr(float *x, Word16 l) +{ + Word16 Q = 15; + for (int i = 0; i < l; i++) + { + if (x[i] >= 1 || x[i] <= -1) + Q = s_min(Q, norm_s((Word16)x[i])); + } + return Q; +} +Word16 Q_factor_arrL(float *x, Word16 l) +{ + Word16 Q = 31; + for (int i = 0; i < l; i++) + { + if (x[i] >= 1 || x[i] <= -1) + Q = s_min(Q, norm_l((Word32)x[i])); + } + return Q; +} diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 4ffd9190a..e36b7432f 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -2480,8 +2480,8 @@ void IGFDecReplicateTCX10State_flt( ); void InitPsychLPC( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t L_frame, /* i : frame length */ + const Word32 sr_core, /* i : sampling rate of core-coder */ + const Word16 L_frame, /* i : frame length */ const TCX_CONFIG_HANDLE hTcxCfg /* i : TCX configuration handle */ ); diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com.c index ac94d56b0..09dcd68b4 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com.c @@ -47,14 +47,14 @@ static void SpectrumWeighting_Init( SpectrumWarping const *pSpectrumWarping, - const int16_t isTCX20, + const Word16 isTCX20, PsychoacousticParameters *pPsychParams ) { - if ( isTCX20 ) + IF ( isTCX20 ) { pPsychParams->bandLengths = pSpectrumWarping->bandLengthsTCX20; } - else + ELSE { pPsychParams->bandLengths = pSpectrumWarping->bandLengthsTCX10; } @@ -69,15 +69,15 @@ static void SpectrumWeighting_Init( *-------------------------------------------------------------------*/ 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 ) { - if ( pPsychParams == NULL ) + IF( pPsychParams == NULL ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "PsychParams handle is NULL" ); } @@ -85,24 +85,24 @@ ivas_error PsychoacousticParameters_Init( pPsychParams->nBins = nBins; pPsychParams->nBands = nBands; - if ( !isWarped ) + IF( !isWarped ) { pPsychParams->bandLengths = NULL; } - else + ELSE { - assert( pPsychParams->nBands == 64 ); - switch ( sr_core ) + assert( EQ_16(pPsychParams->nBands , 64) ); + SWITCH( sr_core ) { case 16000: SpectrumWeighting_Init( sw16000Hz, isTCX20, pPsychParams ); - break; + BREAK; case 25600: SpectrumWeighting_Init( sw25600Hz, isTCX20, pPsychParams ); - break; + BREAK; case 32000: SpectrumWeighting_Init( sw32000Hz, isTCX20, pPsychParams ); - break; + BREAK; default: return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Subband division not defined for this sampling rate" ); } @@ -118,16 +118,16 @@ ivas_error PsychoacousticParameters_Init( *-------------------------------------------------------------------*/ void InitPsychLPC( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t L_frame, /* i : frame length */ + const Word32 sr_core, /* i : sampling rate of core-coder */ + const Word16 L_frame, /* i : frame length */ const TCX_CONFIG_HANDLE hTcxCfg /* i : TCX configuration handle */ ) { - int16_t L_frame_ext = L_frame + L_frame / 4; + Word16 L_frame_ext = add( L_frame, shr( L_frame, 2 ) ); hTcxCfg->psychParamsCurrent = NULL; - PsychoacousticParameters_Init( sr_core, L_frame / 2, 64, 0, 1, &hTcxCfg->psychParamsTCX10 ); + PsychoacousticParameters_Init( sr_core, shr( L_frame, 1 ), 64, 0, 1, &hTcxCfg->psychParamsTCX10 ); PsychoacousticParameters_Init( sr_core, L_frame, 64, 1, 1, &hTcxCfg->psychParamsTCX20 ); PsychoacousticParameters_Init( sr_core, L_frame_ext, 64, 1, 0, &hTcxCfg->psychParamsTCX20AfterACELP ); diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 5a3731b90..3b0ad6485 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -70,6 +70,17 @@ float fix_to_float( Word32 number, Word32 Q ); Word16 float_to_fix16( float number, Word16 Q ); // Word16 to Float float fix16_to_float( Word16 number, Word16 Q ); +void floatToFixed_arrL(const float * f, Word32* i, Word16 Q, Word16 l); +void floatToFixed_arr(const float * f, Word16* i, Word16 Q, Word16 l); +void fixedToFloat_arrL(const Word32 *i, float * f, Word16 Q, Word16 l); +void fixedToFloat_arr(const Word16 *i, float * f, Word16 Q, Word16 l); +Word16 Q_factor(Word16 x); +Word16 Q_factor_L(Word32 x); +Word16 Q_factor_arr(float* x, Word16 l); +Word16 Q_factor_arrL(float* x, Word16 l); +//Handles the cases where Q is negative +Word32 floatToFixed(const float f, Word16 Q); +float fixedToFloat(const Word32 i, Word16 Q); Word32 Mult_32_16( Word32 a, @@ -115,6 +126,11 @@ void Copy( Word16 y[], /* o : output vector */ const Word16 L /* i : vector length */ ); +void Copy_pword( + const PWord16 x[], /* i : input vector */ + PWord16 y[], /* o : output vector */ + const Word16 L /* i : vector length */ +); //tools.c void Scale_sig( @@ -3339,15 +3355,21 @@ Word16 getTcxonly( #endif ); -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 */ +Word16 getTcxonly_fx( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + const Word16 is_ism_format /* i : flag indicating ISM format */ +); +Word16 getCtxHm( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 rf_flag /* i : flag to signal the RF mode */ ); -int16_t getResq( - const int32_t total_brate /* i : total bitrate */ +Word16 getResq( + const Word32 total_brate /* i : total bitrate */ ); Word16 getTnsAllowed( @@ -3362,7 +3384,12 @@ int16_t getRestrictedMode( const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ ); -Word16 sr2fscale(const Word32 sr); +Word16 getMdctWindowLength_fx( + const Word16 fscale ); + +Word16 sr2fscale_fx( +const Word32 sr_core /* i : internal sampling rate */ +); Word32 getCoreSamplerateMode2( const Word16 element_mode, /* i : IVAS element mode */ @@ -3375,22 +3402,22 @@ Word32 getCoreSamplerateMode2( Word16 getTcxBandwidth(const Word16 bandwidth); -Word16 getIgfPresent( +Word16 getIgfPresent_fx( const Word16 element_mode, /* i : IVAS element mode */ const Word32 total_brate, /* i : total bitrate */ const Word16 bwidth, /* i : audio bandwidth */ const Word16 rf_mode /* i : flag to signal the RF mode */ ); -Word16 getCnaPresent( +Word16 getCnaPresent_fx( const Word16 element_mode, /* i : element mode */ const Word32 element_brate, /* i : element bitrate */ const Word32 total_brate, /* i : total bitrate */ const Word16 bwidth /* i : audio bandwidth */ ); -int16_t getTcxLtp( - const int32_t sr_core /* i : internal sampling rate */ +Word16 getTcxLtp( + const Word32 sr_core /* i : internal sampling rate */ ); Word16 initPitchLagParameters( @@ -3556,6 +3583,14 @@ void InitTnsConfigs( const Word16 is_mct ); +#define IVAS_CODE_TCX_UTIL +#ifdef IVAS_CODE_TCX_UTIL +void SetAllowTnsOnWhite( + STnsConfig tnsConfig[2][2], + const Word8 allowTnsOnWhite ); +#endif +#undef IVAS_CODE_TCX_UTIL + void SetTnsConfig( TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */ Word8 isTCX20, @@ -5157,6 +5192,13 @@ void RefineTonalComponents( #endif ); +ivas_error PsychoacousticParameters_Init( + 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 ivas_error TonalMDCTConceal_Init( @@ -5166,6 +5208,13 @@ ivas_error TonalMDCTConceal_Init( const Word16 nScaleFactors, TCX_CONFIG_HANDLE hTcxCfg /* TCX config */ ); +ivas_error TonalMDCTConceal_Init_ivas_fx( + TonalMDCTConcealPtr hTonalMDCTConc, + const UWord16 nSamples, + const UWord16 nSamplesCore, + const UWord16 nScaleFactors, + TCX_CONFIG_HANDLE hTcxCfg /* TCX config */ +); /* Must be called only when a good frame is recieved - concealment is inactive */ void TonalMDCTConceal_SaveFreqSignal( @@ -5373,6 +5422,40 @@ void TonalMDCTConceal_Apply( Word16 *sigIn2, /* i : i signal for fade-in */ Word16 *sigOut /* o : output signal */ ); +void init_tcx_window_cfg_fx( + TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX Config handle */ + const Word32 sr_core, /* i : SR core */ + const Word32 input_Fs, /* i : input/output SR */ + const Word16 L_frame, /* i : L_frame at sr_core */ + const Word16 L_frameTCX, /* i : L_frame at i/o SR */ + const Word16 encoderLookahead_enc, /* i : encoder LA at sr_core */ + const Word16 encoderLookahead_FB, /* i : encoder LA at i/o SR */ + const Word16 mdctWindowLength, /* i : window length at sr_core */ + const Word16 mdctWindowLengthFB, /* i : window length at i/o SR */ + const Word16 element_mode /* i : mode of CPE/SCE */ + ); + +void init_tcx_cfg_fx( + TCX_CONFIG_HANDLE hTcxCfg, + const Word32 total_brate, + const Word32 sr_core, + const Word32 input_Fs, + const Word16 L_frame, + const Word16 bwidth, + const Word16 L_frameTCX, + const Word16 fscale, + const Word16 encoderLookahead_enc, + const Word16 encoderLookahead_FB, + const Word16 preemph_fac, + const Word16 tcxonly, + const Word16 rf_mode, + const Word16 igf, + const Word16 infoIGFStopFreq, + const Word16 element_mode, + const Word16 ini_frame, + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */, + const Word16 fscaleFB + ); //syn_outp_fx.c @@ -6771,6 +6854,22 @@ void TonalMDCTConceal_Apply( #endif ); + void reset_tcx_overl_buf_fx( + TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ + ); + void acelp_plc_mdct_transition_fx( + Decoder_State *st /* i/o: Decoder state */ + ); + void cldfb_reset_memory_fx( + HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */, + Word16 *memory_length ); + void tcxltp_dec_init_fx( + TCX_LTP_DEC_HANDLE hTcxLtpDec, + const Word16 ini_frame, + const Word16 last_codec_mode, + const Word16 element_mode, + const Word16 pit_max, + const Word32 sr_core ); //swb_bwe_dec_hr_fx.c Word16 swb_bwe_dec_hr_fx( diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 0fdc29f90..663001a3a 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -717,6 +717,7 @@ typedef struct cldfb_filter_bank_struct uint16_t memory_length; /* main filter state */ + Word16 *cldfb_state_fx; float *cldfb_state; /* other parameters */ diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index 5e53dcf02..6b647eeba 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -112,10 +112,10 @@ void mdct_window_sine_flt( void mdct_window_sine_IVAS_updated( PWord16 *window, - const int32_t Fs, - const int16_t n, - const int16_t window_type, - const int16_t element_mode) + const Word32 Fs, + const Word16 n, + const Word16 window_type, + const Word16 element_mode) { if (element_mode == EVS_MONO) { diff --git a/lib_com/tcx_utils_fx.c b/lib_com/tcx_utils_fx.c index b3b192784..4af5315b3 100644 --- a/lib_com/tcx_utils_fx.c +++ b/lib_com/tcx_utils_fx.c @@ -1740,6 +1740,7 @@ void SetTnsConfig( hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP]; assert(hTcxCfg->pCurrentTnsConfig != NULL); } +#define IVAS_CODE_TCX_UTIL #ifdef IVAS_CODE_TCX_UTIL /*-------------------------------------------------------------------* * SetAllowTnsOnWhite @@ -1749,7 +1750,7 @@ void SetTnsConfig( void SetAllowTnsOnWhite( STnsConfig tnsConfig[2][2], /* o : updated TNS configurations */ - const int8_t allowTnsOnWhite /* i : flag for TNS in whiteded domain mode */ + const Word8 allowTnsOnWhite /* i : flag for TNS in whiteded domain mode */ ) { tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite; @@ -1760,6 +1761,7 @@ void SetAllowTnsOnWhite( return; } #endif +#undef IVAS_CODE_TCX_UTIL void tcx_get_gain( Word32 *x, /* i: spectrum 1 */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index a75d9d78e..702b456e1 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -316,6 +316,33 @@ void Copy( } } +void Copy_pword( + const PWord16 x[], /* i : input vector */ + PWord16 y[], /* o : output vector */ + const Word16 L /* i : vector length */ +) +{ + Word16 i; + + IF( y < x ) + { + FOR( i = 0; i < L; i++ ) + { + y[i].v.im = x[i].v.im; + y[i].v.re = x[i].v.re; + move16(); + } + } + ELSE + { + FOR( i = L - 1; i >= 0; i-- ) + { + y[i].v.im = x[i].v.im; + y[i].v.re = x[i].v.re; + move16(); + } + } +} /*-------------------------------------------------------------------* * Copy32: * diff --git a/lib_dec/amr_wb_dec_fx.c b/lib_dec/amr_wb_dec_fx.c index 82fbff42d..137e7b8aa 100644 --- a/lib_dec/amr_wb_dec_fx.c +++ b/lib_dec/amr_wb_dec_fx.c @@ -150,7 +150,7 @@ ivas_error amr_wb_dec_fx( st_fx->sr_core = i_mult(st_fx->L_frame,50); st_fx->fscale_old = st_fx->fscale; - st_fx->fscale = sr2fscale(st_fx->sr_core); + st_fx->fscale = sr2fscale_fx(st_fx->sr_core); /* Initialization in case that the first frame is the good received AMR-WB (IO) frame */ IF( st_fx->ini_frame == 0 ) diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index ade189e09..d9f284c8c 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -41,7 +41,7 @@ #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" - +#include "prot_fx2.h" /*-----------------------------------------------------------------------* * open_decoder_LPD_flt() * @@ -187,7 +187,105 @@ void open_decoder_LPD_flt( { if (!is_init || st->element_mode != IVAS_CPE_MDCT) { +#ifdef IVAS_FLOAT_FIXED + init_tcx_cfg_fx(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,fscaleFB); + st->hTcxCfg->preemph_fac_flt = st->preemph_fac_float; + st->hTcxCfg->sq_rounding_flt = fix16_to_float(st->hTcxCfg->sq_rounding, 15); + st->hTcxCfg->bandwidth_flt = fix16_to_float(st->hTcxCfg->bandwidth, 15); + st->hTcxCfg->na_scale_flt = fix16_to_float(st->hTcxCfg->na_scale, 15); + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_length / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_flt[st->hTcxCfg->tcx_mdct_window_length - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_lengthFB / 2; i++) + { + st->hTcxCfg->tcx_mdct_windowFB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_windowFB[i].v.im, 15); + st->hTcxCfg->tcx_mdct_windowFB_flt[st->hTcxCfg->tcx_mdct_window_lengthFB - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_windowFB[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_trans_length / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_trans_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_trans[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_trans_flt[st->hTcxCfg->tcx_mdct_window_trans_length - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_trans[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_trans_lengthFB / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_transFB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_transFB[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_transFB_flt[st->hTcxCfg->tcx_mdct_window_trans_lengthFB - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_transFB[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_half_length / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_half_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_half[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_half_flt[st->hTcxCfg->tcx_mdct_window_half_length - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_half[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_half_lengthFB / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_halfFB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_halfFB[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_halfFB_flt[st->hTcxCfg->tcx_mdct_window_half_lengthFB - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_halfFB[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_min_length / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_minimum_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_minimum[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_minimum_flt[st->hTcxCfg->tcx_mdct_window_min_length - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_minimum[i].v.re, 15); + } + FOR (i = 0; i < st->hTcxCfg->tcx_mdct_window_min_lengthFB / 2; i++) + { + st->hTcxCfg->tcx_mdct_window_minimumFB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.im, 15); + st->hTcxCfg->tcx_mdct_window_minimumFB_flt[st->hTcxCfg->tcx_mdct_window_min_lengthFB - i - 1] = fix16_to_float(st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re, 15); + } + Word16 n = st->L_frame; + Word16 n0 = shr(imult1616(n, 9), 5); + Word16 n1 = shr(imult1616(n, 23), 5); /* left slope length */ + Word16 n2 = shr(imult1616(n, 14), 5); /* right slope length */ + FOR (i = 0; i < n0; i++) + { + st->hTcxCfg->tcx_aldo_window_1_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_1[i], 15); + } + FOR (i = n0; i < n / 2; i++) + { + st->hTcxCfg->tcx_aldo_window_1_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_1_trunc[i - n0].v.im, 15); + } + FOR (i = 0; i < n1 - n / 2; i++) + { + st->hTcxCfg->tcx_aldo_window_1_flt[n / 2 + i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_1_trunc[n1 - n / 2 - 1 - i].v.re, 15); + } + FOR (i = 0; i < n2 / 2; i++) + { + st->hTcxCfg->tcx_aldo_window_2_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_2[i].v.im, 15); + } + FOR (i = n2 / 2; i < n2; i++) + { + st->hTcxCfg->tcx_aldo_window_2_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_2[n2 - i - 1].v.re, 15); + } + n = NS2SA_fx2(st->output_Fs, FRAME_SIZE_NS); + n0 = shr(imult1616(n, 9), 5); + n1 = shr(imult1616(n, 23), 5); /* left slope length */ + n2 = shr(imult1616(n, 14), 5); /* right slope length */ + FOR (i = 0; i < n0; i++) + { + st->hTcxCfg->tcx_aldo_window_1_FB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_1_FB[i], 15); + } + FOR (i = n0; i < n / 2; i++) + { + st->hTcxCfg->tcx_aldo_window_1_FB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_1_FB_trunc[i - n0].v.im, 15); + } + FOR (i = 0; i < n1 - n / 2; i++) + { + st->hTcxCfg->tcx_aldo_window_1_FB_flt[n / 2 + i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_1_FB_trunc[n1 - n / 2 - i - 1].v.re, 15); + } + FOR (i = 0; i < n2 / 2; i++) + { + st->hTcxCfg->tcx_aldo_window_2_FB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_2_FB[i].v.im, 15); + } + FOR (i = n2 / 2; i < n2; i++) + { + st->hTcxCfg->tcx_aldo_window_2_FB_flt[i] = fix16_to_float(st->hTcxCfg->tcx_aldo_window_2_FB[n2 - i - 1].v.re, 15); + } + st->hTcxCfg->tcx_aldo_window_1_trunc_flt = st->hTcxCfg->tcx_aldo_window_1_flt + NS2SA(st->sr_core, N_ZERO_MDCT_NS); + st->hTcxCfg->tcx_aldo_window_1_FB_trunc_flt = st->hTcxCfg->tcx_aldo_window_1_FB_flt + NS2SA(st->output_Fs, N_ZERO_MDCT_NS); +#else 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_float, st->tcxonly, st->rf_flag, st->igf, st->hIGFDec->infoIGFStopFreq, st->element_mode, st->ini_frame, MCT_flag); +#endif } else { @@ -220,7 +318,15 @@ void open_decoder_LPD_flt( if (st->hTcxDec != NULL) { +#ifdef IVAS_FLOAT_FIXED + reset_tcx_overl_buf_fx(st->hTcxDec); + fixedToFloat_arr(hTcxDec->old_syn_Overl, hTcxDec->old_syn_Overl_float, 0, L_FRAME32k / 2); + fixedToFloat_arr(hTcxDec->syn_Overl_TDAC, hTcxDec->syn_Overl_TDAC_float, 0, L_FRAME32k / 2); + fixedToFloat_arr(hTcxDec->syn_Overl, hTcxDec->syn_Overl_float, 0, L_FRAME32k / 2); + fixedToFloat_arr(hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDACFB_float, 0, L_FRAME_MAX / 2); +#else reset_tcx_overl_buf(st->hTcxDec); +#endif // IVAS_FLOAT_FIXED set_zero(st->hTcxDec->syn_OverlFB_float, L_FRAME_MAX / 2); set_zero(st->hTcxDec->old_synth_float, OLD_SYNTH_INTERNAL_DEC); @@ -280,7 +386,30 @@ void open_decoder_LPD_flt( { /* Switching from Mode 1 ACELP */ st->last_core_bfi = ACELP_CORE; +#ifdef IVAS_FLOAT_FIXED + Word16 delay_comp = NS2SA_fx2(st->output_Fs, DELAY_CLDFB_NS); /*CLDFB delay*/ + Word16 Q_fer_samples = Q_factor_arr(st->hHQ_core->fer_samples + delay_comp, shr(st->hTcxDec->L_frameTCX, 1)) - 1; + IF(st->prev_bfi != 0 && st->hTcxCfg != NULL) + { + floatToFixed_arr(st->hHQ_core->fer_samples + delay_comp, st->hHQ_core->fer_samples_fx + delay_comp, Q_fer_samples, shr(st->hTcxDec->L_frameTCX, 1)); + floatToFixed_arr(st->hTcxDec->syn_OverlFB_float, st->hTcxDec->syn_OverlFB, Q_fer_samples, L_FRAME_MAX / 2); + floatToFixed_arr(st->hTcxDec->syn_Overl_float, st->hTcxDec->syn_Overl, Q_fer_samples, L_FRAME32k / 2); + floatToFixed_arr(st->hHQ_core->old_out, st->hHQ_core->old_out_fx, Q_fer_samples - 1, L_FRAME48k); + floatToFixed_arr(st->hHQ_core->old_outLB, st->hHQ_core->old_out_LB_fx, Q_fer_samples - 1, L_FRAME32k); + floatToFixed_arr(st->hTcxDec->syn_Overl_TDACFB_float, st->hTcxDec->syn_Overl_TDACFB, Q_fer_samples - 1, L_FRAME_MAX / 2); + floatToFixed_arr(st->hTcxDec->syn_Overl_TDAC_float, st->hTcxDec->syn_Overl_TDAC, Q_fer_samples - 1, L_FRAME32k / 2); + acelp_plc_mdct_transition_fx(st); + fixedToFloat_arr(st->hTcxDec->syn_OverlFB, st->hTcxDec->syn_OverlFB_float, Q_fer_samples, L_FRAME_MAX / 2); + fixedToFloat_arr(st->hTcxDec->syn_Overl, st->hTcxDec->syn_Overl_float, Q_fer_samples, L_FRAME32k / 2); + fixedToFloat_arr(st->hHQ_core->old_out_fx, st->hHQ_core->old_out, Q_fer_samples - 1, L_FRAME48k); + fixedToFloat_arr(st->hHQ_core->old_out_LB_fx, st->hHQ_core->old_outLB, Q_fer_samples - 1, L_FRAME32k); + fixedToFloat_arr(st->hTcxDec->syn_Overl_TDACFB, st->hTcxDec->syn_Overl_TDACFB_float, Q_fer_samples - 1, L_FRAME_MAX / 2); + fixedToFloat_arr(st->hTcxDec->syn_Overl_TDAC, st->hTcxDec->syn_Overl_TDAC_float, Q_fer_samples - 1, L_FRAME32k / 2); + } +#else acelp_plc_mdct_transition(st); +#endif // IVAS_FLOAT_FIXED + } if (st->last_codec_mode == MODE2 && @@ -306,7 +435,16 @@ void open_decoder_LPD_flt( /*OLA -> zero */ if (st->hTcxDec != NULL) { +#ifdef IVAS_FLOAT_FIXED + reset_tcx_overl_buf_fx(st->hTcxDec); + fixedToFloat_arr(hTcxDec->old_syn_Overl, hTcxDec->old_syn_Overl_float, 0, L_FRAME32k / 2); + fixedToFloat_arr(hTcxDec->syn_Overl_TDAC, hTcxDec->syn_Overl_TDAC_float, 0, L_FRAME32k / 2); + fixedToFloat_arr(hTcxDec->syn_Overl, hTcxDec->syn_Overl_float, 0, L_FRAME32k / 2); + fixedToFloat_arr(hTcxDec->syn_Overl_TDACFB, hTcxDec->syn_Overl_TDACFB_float, 0, L_FRAME_MAX / 2); +#else reset_tcx_overl_buf(st->hTcxDec); +#endif // IVAS_FLOAT_FIXED + } if (st->hTcxCfg != NULL) @@ -330,12 +468,27 @@ void open_decoder_LPD_flt( } /* reset CLDFB memories */ +#ifdef IVAS_FLOAT_FIXED + Word16 memory_length=0; + cldfb_reset_memory_fx(st->cldfbAna,&memory_length); + fixedToFloat_arr(st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, 0, memory_length); + cldfb_reset_memory_fx(st->cldfbBPF,&memory_length); + fixedToFloat_arr(st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, 0, memory_length); + cldfb_reset_memory_fx(st->cldfbSyn,&memory_length); + fixedToFloat_arr(st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_state, 0, memory_length); + #else cldfb_reset_memory_ivas(st->cldfbAna); cldfb_reset_memory_ivas(st->cldfbBPF); cldfb_reset_memory_ivas(st->cldfbSyn); +#endif // IVAS_FLOAT_FIXED if (st->cldfbSynHB != NULL) { + #ifdef IVAS_FLOAT_FIXED + cldfb_reset_memory_fx(st->cldfbSynHB,&memory_length); + fixedToFloat_arr(st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_state, 0, memory_length); + #else cldfb_reset_memory_ivas(st->cldfbSynHB); + #endif } } else if ((st->L_frame != st->last_L_frame) && (st->L_frame <= L_FRAME16k) && (st->last_L_frame <= L_FRAME16k)) /* Rate switching between 12.8 and 16 kHz*/ @@ -585,7 +738,20 @@ void open_decoder_LPD_flt( /* TCX-LTP */ if (hTcxLtpDec != NULL) { +#ifdef IVAS_FLOAT_FIXED + tcxltp_dec_init_fx(hTcxLtpDec, st->ini_frame, st->last_codec_mode, st->element_mode, st->pit_max, st->sr_core); + IF(st->ini_frame == 0 || (EQ_16(st->last_codec_mode, MODE1) && EQ_16(st->element_mode, EVS_MONO))) + { + IF(st->ini_frame == 0) + { + fixedToFloat_arr(hTcxLtpDec->tcxltp_mem_in,hTcxLtpDec->tcxltp_mem_in_float, 0, TCXLTP_MAX_DELAY); + fixedToFloat_arr(hTcxLtpDec->tcxltp_mem_out,hTcxLtpDec->tcxltp_mem_out_float, 0, L_FRAME48k); + hTcxLtpDec->tcxltp_gain_post_prev_float = fixedToFloat(hTcxLtpDec->tcxltp_gain_post_prev,0); + } + } +#else tcxltp_dec_init(hTcxLtpDec, st->ini_frame, st->last_codec_mode, st->element_mode, st->pit_max, st->sr_core); +#endif // IVAS_FLOAT_FIXED } /* TCX */ @@ -669,7 +835,29 @@ void open_decoder_LPD_flt( st->hTonalMDCTConc->lastBlockData.tonalConcealmentActive = 0; st->hTonalMDCTConc->lastBlockData.nSamples = 0; +#ifdef IVAS_FLOAT_FIXED + TonalMDCTConceal_Init_ivas_fx( st->hTonalMDCTConc, st->hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg ); + st->hTonalMDCTConc->lastBlockData.spectralData_float = st->hTonalMDCTConc->spectralDataBuffers_float[0]; + st->hTonalMDCTConc->secondLastBlockData.spectralData_float = st->hTonalMDCTConc->spectralDataBuffers_float[1]; + st->hTonalMDCTConc->secondLastPowerSpectrum_float = st->hTonalMDCTConc->secondLastBlockData.spectralData_float; + st->hTonalMDCTConc->lastBlockData.scaleFactors_float = st->hTonalMDCTConc->scaleFactorsBuffers_float[0]; + st->hTonalMDCTConc->secondLastBlockData.scaleFactors_float = st->hTonalMDCTConc->scaleFactorsBuffers_float[1]; + st->hTonalMDCTConc->pTCI_float = (TonalComponentsInfo_float *) st->hTonalMDCTConc->timeDataBuffer_float; + st->hTonalMDCTConc->lastPitchLag_float = 0; + FOR( i = 0; i < FDNS_NPTS; i++ ) + { + st->hTonalMDCTConc->scaleFactorsBackground_flt[i] = fix16_to_float( st->hTonalMDCTConc->scaleFactorsBackground[i], 0 ); + } + st->hTonalMDCTConc->scf_fadeout_flt = 1.0f; + st->hTonalMDCTConc->last_block_nrg_flt = 0.0f; + st->hTonalMDCTConc->curr_noise_nrg_flt = 0.0f; + st->hTonalMDCTConc->faded_signal_nrg_flt = 0.0f; + st->hTonalMDCTConc->secondLastPcmOut_float = &st->hTonalMDCTConc->timeDataBuffer_float[( 3 * L_FRAME_MAX ) / 2 - imult1616( 3, shr( s_min( L_FRAME_MAX, st->hTcxDec->L_frameTCX ), 1 ) )]; + st->hTonalMDCTConc->lastPcmOut_float = &st->hTonalMDCTConc->timeDataBuffer_float[( 3 * L_FRAME_MAX ) / 2 - s_min( L_FRAME_MAX, st->hTcxDec->L_frameTCX )]; + assert( sizeof( *st->hTonalMDCTConc->pTCI_float ) <= ( st->hTonalMDCTConc->lastPcmOut_float - st->hTonalMDCTConc->timeDataBuffer_float ) * sizeof( st->hTonalMDCTConc->timeDataBuffer_float[0] ) ); +#else TonalMDCTConceal_Init_ivas(st->hTonalMDCTConc, st->hTcxDec->L_frameTCX, st->L_frame, FDNS_NPTS, st->hTcxCfg); +#endif // IVAS_FLOAT_FIXED } st->last_tns_active = 0; @@ -772,6 +960,16 @@ void reset_tcx_overl_buf( return; } +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*/ + set16_fx(hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2); /*HQ-CORE(bfi)->TCX don't need it*/ + set16_fx(hTcxDec->syn_Overl, 0, L_FRAME32k / 2); /*HQ-CORE(bfi)->TCX don't need it*/ + set16_fx(hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2); /*HQ-CORE(bfi)->TCX don't need it*/ + return; +} /*-----------------------------------------------------------------------* * acelp_plc_mdct_transition() diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index f9d8aabd3..b1b8005ba 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -61,8 +61,8 @@ void open_decoder_LPD( } st->sr_core = getCoreSamplerateMode2(st->element_mode, st->total_brate, bwidth, st->flag_ACELP16k, st->rf_flag , st->is_ism_format ); - st->fscale = sr2fscale(st->sr_core); - fscaleFB = sr2fscale(st->output_Fs); + st->fscale = sr2fscale_fx(st->sr_core); + fscaleFB = sr2fscale_fx(st->output_Fs); /* initializing variables for frame lengths etc. right in the beginning */ st->L_frame = extract_l(Mult_32_16(st->sr_core , 0x0290)); @@ -1008,3 +1008,79 @@ void open_decoder_LPD( return; } +void tcxltp_dec_init_fx( + TCX_LTP_DEC_HANDLE hTcxLtpDec, + const Word16 ini_frame, + const Word16 last_codec_mode, + const Word16 element_mode, + const Word16 pit_max, + const Word32 sr_core ) +{ + hTcxLtpDec->tcxltp_gain = 0; + + hTcxLtpDec->tcxltp = getTcxLtp( sr_core ); + + IF( ini_frame == 0 || ( EQ_16( last_codec_mode, MODE1 ) && EQ_16( element_mode, EVS_MONO ) ) ) + { + hTcxLtpDec->tcxltp_pitch_int = pit_max; + hTcxLtpDec->tcxltp_pitch_fr = 0; + + IF( ini_frame == 0 ) + { + set16_fx( hTcxLtpDec->tcxltp_mem_in, 0, TCXLTP_MAX_DELAY ); + set16_fx( hTcxLtpDec->tcxltp_mem_out, 0, L_FRAME48k ); + hTcxLtpDec->tcxltp_pitch_int_post_prev = 0; + hTcxLtpDec->tcxltp_pitch_fr_post_prev = 0; + hTcxLtpDec->tcxltp_gain_post_prev = 0; + hTcxLtpDec->tcxltp_filt_idx_prev = -1; + } + } + + return; +} +void acelp_plc_mdct_transition_fx( + Decoder_State *st /* i/o: Decoder state */ +) +{ + PWord16 const *w; + Word16 W1, W2, nz, delay_comp; + Word16 i; + + /*PLC*/ + IF( st->prev_bfi != 0 && st->hTcxCfg != NULL ) + { + W1 = st->hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + W2 = shr( st->hTcxCfg->tcx_mdct_window_lengthFB, 1 ); + w = st->hTcxCfg->tcx_mdct_windowFB; /*pointer - no need to instrument*/ + + nz = NS2SA_fx2( st->output_Fs, N_ZERO_MDCT_NS ); + delay_comp = NS2SA_fx2( st->output_Fs, DELAY_CLDFB_NS ); /*CLDFB delay*/ + + Copy( st->hHQ_core->fer_samples_fx + delay_comp, st->hTcxDec->syn_OverlFB, shr( st->hTcxDec->L_frameTCX, 1 ) ); + lerp( st->hHQ_core->fer_samples_fx + delay_comp, st->hTcxDec->syn_Overl, shr( st->L_frame, 1 ), shr( st->hTcxDec->L_frameTCX, 1 ) ); /*ACELP(bfi)->TCX(rect)*/ + /*old_out needed for MODE1 routine and syn_Overl_TDAC for MODE2 routine*/ + st->hHQ_core->Q_old_wtda = -1; + set16_fx( st->hHQ_core->old_out_fx, 0, nz ); // Q_old_out is 0 + Copy_Scale_sig( st->hHQ_core->fer_samples_fx + delay_comp, st->hHQ_core->old_out_fx + nz, W1, st->hHQ_core->Q_old_wtda ); /*Q-1*/ + + FOR( i = 0; i < W2; i++ ) + { + st->hHQ_core->old_out_fx[i + nz] = round_fx( Mpy_32_16_1( L_mult( w[i].v.re, w[i].v.re ), st->hHQ_core->old_out_fx[i + nz] ) ); + } + FOR( ; i < W1; i++ ) + { + st->hHQ_core->old_out_fx[i + nz] = round_fx( Mpy_32_16_1( L_mult( w[W2 - 1 - ( i - W2 )].v.im, w[W2 - 1 - ( i - W2 )].v.im ), st->hHQ_core->old_out_fx[i + nz] ) ); + } + set16_fx( &st->hHQ_core->old_out_fx[W1 + nz], 0, nz ); + + lerp( st->hHQ_core->old_out_fx, st->hHQ_core->old_out_LB_fx, st->L_frame, st->hTcxDec->L_frameTCX ); + Copy( st->hHQ_core->old_out_fx + nz, st->hTcxDec->syn_Overl_TDACFB, shr( st->hTcxDec->L_frameTCX, 1 ) ); + + nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS ); + Copy( st->hHQ_core->old_out_LB_fx + nz, st->hTcxDec->syn_Overl_TDAC, shr( st->L_frame, 1 ) ); + st->hHQ_core->Q_old_wtda_LB = st->hHQ_core->Q_old_wtda; + } + + return; +} diff --git a/lib_dec/core_dec_reconf_fx.c b/lib_dec/core_dec_reconf_fx.c index d2abbbdb3..6ecfa7ab1 100644 --- a/lib_dec/core_dec_reconf_fx.c +++ b/lib_dec/core_dec_reconf_fx.c @@ -59,7 +59,7 @@ void reconfig_decoder_LPD( IF (NE_16(st->element_mode, IVAS_SCE)) { - st->flag_cna = (Word8)getCnaPresent(st->element_mode, st->element_brate, total_brate, bwidth); + st->flag_cna = (Word8)getCnaPresent_fx(st->element_mode, st->element_brate, total_brate, bwidth); } move16(); diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index eae80e023..e1e99540a 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -50,7 +50,7 @@ void mode_switch_decoder_LPD( sr_core = getCoreSamplerateMode2(st->element_mode, total_brate, bwidth, st->flag_ACELP16k, st->rf_flag, st->is_ism_format ); - fscale = sr2fscale(sr_core); + fscale = sr2fscale_fx(sr_core); move16(); /* set number of coded lines */ @@ -76,7 +76,7 @@ void mode_switch_decoder_LPD( move16(); } - st->igf = getIgfPresent(st->element_mode, total_brate, bwidth, st->rf_flag); + st->igf = getIgfPresent_fx(st->element_mode, total_brate, bwidth, st->rf_flag); IF(st->hIGFDec != NULL) { diff --git a/lib_dec/decision_matrix_dec_fx.c b/lib_dec/decision_matrix_dec_fx.c index 766cad69f..1eb45e6ca 100644 --- a/lib_dec/decision_matrix_dec_fx.c +++ b/lib_dec/decision_matrix_dec_fx.c @@ -129,7 +129,7 @@ void decision_matrix_dec_fx( move32(); st->L_frame = L_FRAME; move16(); - st->fscale = sr2fscale(INT_FS_FX); + st->fscale = sr2fscale_fx(INT_FS_FX); move16(); IF ( st->ini_frame == 0 ) diff --git a/lib_dec/evs_dec_fx.c b/lib_dec/evs_dec_fx.c index bb4637d1f..d71eb2db7 100644 --- a/lib_dec/evs_dec_fx.c +++ b/lib_dec/evs_dec_fx.c @@ -283,7 +283,7 @@ ivas_error evs_dec_fx( { st_fx->sr_core = i_mult(st_fx->L_frame, FRAMES_PER_SEC); st_fx->fscale_old = st_fx->fscale; - st_fx->fscale = sr2fscale(st_fx->sr_core); + st_fx->fscale = sr2fscale_fx(st_fx->sr_core); } ELSE { diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 68c602e88..1ce509844 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -773,7 +773,7 @@ Word16 ApplyFdCng ( 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, scf, DEC); + 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); diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index d5d99d8d2..cdc8d3853 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -1136,11 +1136,11 @@ void ivas_mdct_core_tns_ns( float fade_in, fade_out; scf_last = &st->hTonalMDCTConc->lastBlockData.scaleFactors_float[0]; - scf_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; + scf_bg = &st->hTonalMDCTConc->scaleFactorsBackground_flt[0]; - st->hTonalMDCTConc->scf_fadeout *= 0.95f; + st->hTonalMDCTConc->scf_fadeout_flt *= 0.95f; - fade_out = st->hTonalMDCTConc->scf_fadeout; + fade_out = st->hTonalMDCTConc->scf_fadeout_flt; fade_in = 1 - fade_out; for ( int16_t i = 0; i < st->hTonalMDCTConc->nScaleFactors; i++ ) @@ -1150,7 +1150,7 @@ void ivas_mdct_core_tns_ns( } else { - st->hTonalMDCTConc->scf_fadeout = 1.0f; + st->hTonalMDCTConc->scf_fadeout_flt = 1.0f; mvr2r( st->hTonalMDCTConc->lastBlockData.scaleFactors_float, &sns_int_scf[0], st->hTonalMDCTConc->nScaleFactors ); } } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 21daf233a..367cf1749 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -352,15 +352,20 @@ typedef struct tonalmdctconceal Word16 secondLastPowerSpectrum_exp; - float scaleFactorsBackground[FDNS_NPTS]; - float scf_fadeout; + float scaleFactorsBackground_flt[FDNS_NPTS]; + Word16 scaleFactorsBackground[FDNS_NPTS]; + float scf_fadeout_flt; + Word16 scf_fadeout; PsychoacousticParameters *psychParams; PsychoacousticParameters psychParamsTCX20; PsychoacousticParameters psychParamsTCX10; - float last_block_nrg; - float curr_noise_nrg; - float faded_signal_nrg; + float last_block_nrg_flt; + float curr_noise_nrg_flt; + float faded_signal_nrg_flt; + Word16 last_block_nrg; + Word16 curr_noise_nrg; + Word16 faded_signal_nrg; float nFramesLost_float; Word16 nFramesLost; diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 5bfd6322c..1862d5036 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -93,15 +93,15 @@ ivas_error TonalMDCTConceal_Init_ivas( hTonalMDCTConc->nSamplesCore = nSamplesCore; hTonalMDCTConc->nScaleFactors = nScaleFactors; - set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS ); - hTonalMDCTConc->scf_fadeout = 1.0f; + set_zero( hTonalMDCTConc->scaleFactorsBackground_flt, FDNS_NPTS ); + hTonalMDCTConc->scf_fadeout_flt = 1.0f; 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->last_block_nrg = 0.0f; - hTonalMDCTConc->curr_noise_nrg = 0.0f; - hTonalMDCTConc->faded_signal_nrg = 0.0f; + hTonalMDCTConc->last_block_nrg_flt = 0.0f; + hTonalMDCTConc->curr_noise_nrg_flt = 0.0f; + hTonalMDCTConc->faded_signal_nrg_flt = 0.0f; /* Offset the pointer to the end of buffer, so that pTCI_float is not destroyed when new time samples are stored in lastPcmOut */ @@ -166,11 +166,11 @@ void TonalMDCTConceal_SaveFreqSignal_ivas( /* Store new data */ int16_t i; - hTonalMDCTConc->last_block_nrg = 0.0f; + hTonalMDCTConc->last_block_nrg_flt = 0.0f; for ( i = 0; i < infoIGFStartLine; i++ ) { hTonalMDCTConc->lastBlockData.spectralData_float[i] = mdctSpectrum[i]; - hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i]; + hTonalMDCTConc->last_block_nrg_flt += mdctSpectrum[i] * mdctSpectrum[i]; } for ( ; i < nNewSamples; i++ ) { @@ -554,7 +554,7 @@ void TonalMDCTConceal_InsertNoise_ivas( tilt = 1.0f; nrgNoiseInLastFrame = 0.0f; nrgWhiteNoise = 0.0f; - hTonalMDCTConc->faded_signal_nrg = 0.0f; + hTonalMDCTConc->faded_signal_nrg_flt = 0.0f; last_block_nrg_correct = 0.0f; if ( !hTonalMDCTConc->lastBlockData.blockIsValid ) @@ -589,7 +589,7 @@ void TonalMDCTConceal_InsertNoise_ivas( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg_flt ); for ( i = 0; i < crossOverFreq; i++ ) { @@ -605,7 +605,7 @@ void TonalMDCTConceal_InsertNoise_ivas( mdctSpectrum[i] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[i] * mdctSpectrum[i]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) { @@ -629,7 +629,7 @@ void TonalMDCTConceal_InsertNoise_ivas( if ( l < crossOverFreq ) { last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData_float[l] * hTonalMDCTConc->lastBlockData.spectralData_float[l]; - hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l]; + hTonalMDCTConc->curr_noise_nrg_flt -= concealment_noise[l] * concealment_noise[l]; } } } @@ -683,7 +683,7 @@ void TonalMDCTConceal_InsertNoise_ivas( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg_flt ); for ( l = 0; l < hTonalMDCTConc->pTCI_float->lowerIndex[0]; l++ ) { @@ -698,7 +698,7 @@ void TonalMDCTConceal_InsertNoise_ivas( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; } for ( i = 1; i < hTonalMDCTConc->pTCI_float->numIndexes; i++ ) { @@ -715,7 +715,7 @@ void TonalMDCTConceal_InsertNoise_ivas( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; } } @@ -732,7 +732,7 @@ void TonalMDCTConceal_InsertNoise_ivas( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) @@ -742,11 +742,11 @@ void TonalMDCTConceal_InsertNoise_ivas( } } - if ( hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG ) + 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 - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg ); + 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 ); } } @@ -1125,7 +1125,7 @@ void TonalMdctConceal_create_concealment_noise_ivas( } /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; + 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 */ @@ -1135,7 +1135,7 @@ void TonalMdctConceal_create_concealment_noise_ivas( *rnd_c = own_random( rnd_c ); concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i]; - hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[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 ) ) */ @@ -1147,7 +1147,7 @@ void TonalMdctConceal_create_concealment_noise_ivas( *rnd_c = own_random( rnd_c ); concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i]; - hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i]; + hTonalMDCTConc->curr_noise_nrg_flt += concealment_noise[i] * concealment_noise[i]; *rnd_c = own_random( rnd_c ); } @@ -1190,7 +1190,7 @@ void TonalMdctConceal_whiten_noise_shape_ivas( push_wmops( "apply_sns_on_noise_shape" ); - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_flt[0]; psychParams = st->hTonalMDCTConc->psychParams; hFdCngCom = st->hFdCngDec->hFdCngCom; diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index 3117d1427..23a3b526d 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -103,14 +103,14 @@ ivas_error TonalMDCTConceal_Init( move16(); #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT PMTE() - set_zero(hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS); + set_zero(hTonalMDCTConc->scaleFactorsBackground_flt, 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; + hTonalMDCTConc->scf_fadeout_flt = 1.0f; + hTonalMDCTConc->last_block_nrg_flt = 0.0f; + hTonalMDCTConc->curr_noise_nrg_flt = 0.0f; + hTonalMDCTConc->faded_signal_nrg_flt = 0.0f; #endif /* Offset the pointer to the end of buffer, so that pTCI_fix is not destroyed when @@ -127,7 +127,93 @@ ivas_error TonalMDCTConceal_Init( #endif return IVAS_ERR_OK; } +ivas_error TonalMDCTConceal_Init_ivas_fx( + TonalMDCTConcealPtr hTonalMDCTConc, + const UWord16 nSamples, + const UWord16 nSamplesCore, + const UWord16 nScaleFactors, + TCX_CONFIG_HANDLE hTcxCfg ) +{ + test(); + IF( GT_16( nSamples, L_FRAME_MAX ) || GT_16( nScaleFactors, FDNS_NPTS ) ) + { + assert( LE_16(nSamples , L_FRAME_MAX) ); + assert( LE_16(nScaleFactors , FDNS_NPTS) ); + return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) ); + } + assert( EQ_16( hTonalMDCTConc->nScaleFactors , nScaleFactors ) || NE_16( hTonalMDCTConc->nSamples , nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */ + + hTonalMDCTConc->tcx_cfg = hTcxCfg; + hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1]; + move16(); + hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData; + move16(); + hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0]; + move16(); + hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1]; + move16(); + hTonalMDCTConc->lastBlockData.blockIsValid = 0; + move16(); + hTonalMDCTConc->secondLastBlockData.blockIsValid = 0; + move16(); + hTonalMDCTConc->nSamples = 0; + move16(); + hTonalMDCTConc->nScaleFactors = 0; + move16(); + + hTonalMDCTConc->lastBlockData.blockIsConcealed = 0; + move16(); + hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0; + move16(); + hTonalMDCTConc->pTCI_fix = (TonalComponentsInfo_fix *) hTonalMDCTConc->timeDataBuffer; + move16(); + hTonalMDCTConc->lastPitchLag = L_deposit_l( 0 ); + + IF( NE_16( hTonalMDCTConc->nSamples, nSamples ) ) + { + hTonalMDCTConc->secondLastBlockData.blockIsValid = 0; + move16(); + hTonalMDCTConc->lastBlockData.blockIsValid = 0; + move16(); + } + hTonalMDCTConc->nSamples = nSamples; + move16(); + hTonalMDCTConc->nSamplesCore = nSamplesCore; + move16(); + hTonalMDCTConc->nScaleFactors = nScaleFactors; + move16(); + + //#ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT + // PMTE() + // To be uncommented when field of fixed type is added for scaleFactorsBackground + set16_fx( hTonalMDCTConc->scaleFactorsBackground, 0, FDNS_NPTS ); + hTonalMDCTConc->scf_fadeout = 16384 /*1.000000 Q14*/; + 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->last_block_nrg = 0; + hTonalMDCTConc->curr_noise_nrg = 0; + hTonalMDCTConc->faded_signal_nrg = 0; + + /* Offset the pointer to the end of buffer, so that pTCI_fix is not destroyed when + new time samples are stored in lastPcmOut */ + move16(); + move16(); + /* just the second half of the second last pcm output is needed */ + hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub( ( 3 * L_FRAME_MAX ) / 2, imult1616(3 , shr(s_min( L_FRAME_MAX, nSamples ),1 ) ) )]; + hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub( ( 3 * L_FRAME_MAX ) / 2, s_min( L_FRAME_MAX, nSamples ) )]; + /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */ +#if 1 + // TO do enable when only fix code is present currently disabled due to float array in structure + assert( sizeof( *hTonalMDCTConc->pTCI_fix ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) ); +#endif + + return IVAS_ERR_OK; +} void TonalMDCTConceal_SaveFreqSignal( TonalMDCTConcealPtr hTonalMDCTConc, const Word32 *mdctSpectrum, @@ -231,11 +317,11 @@ void TonalMDCTConceal_SaveFreqSignal( #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT int16_t i; PMTE() - hTonalMDCTConc->last_block_nrg = 0.0f; + hTonalMDCTConc->last_block_nrg_flt = 0.0f; for (i = 0; i < infoIGFStartLine; i++) { hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i]; - hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i]; + hTonalMDCTConc->last_block_nrg_flt += mdctSpectrum[i] * mdctSpectrum[i]; } for (; i < nNewSamples; i++) { @@ -802,7 +888,7 @@ void TonalMDCTConceal_InsertNoise( tilt = 1.0f; nrgNoiseInLastFrame = 0.0f; nrgWhiteNoise = 0.0f; - hTonalMDCTConc->faded_signal_nrg = 0.0f; + hTonalMDCTConc->faded_signal_nrg_flt = 0.0f; last_block_nrg_correct = 0.0f; #endif IF (hTonalMDCTConc->lastBlockData.blockIsValid == 0) @@ -839,7 +925,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float)sqrt(cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg); + g *= (float)sqrt(cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg_flt); for (i = 0; i < crossOverFreq; i++) { @@ -855,7 +941,7 @@ void TonalMDCTConceal_InsertNoise( mdctSpectrum[i] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[i] * mdctSpectrum[i]; } for (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) { @@ -879,7 +965,7 @@ void TonalMDCTConceal_InsertNoise( if (l < crossOverFreq) { last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l]; - hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l]; + hTonalMDCTConc->curr_noise_nrg_flt -= concealment_noise[l] * concealment_noise[l]; } } } @@ -933,7 +1019,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float)sqrt(cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg); + g *= (float)sqrt(cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg_flt); for (l = 0; l < hTonalMDCTConc->pTCI_fix->lowerIndex[0]; l++) { @@ -948,7 +1034,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; } for (i = 1; i < hTonalMDCTConc->pTCI_fix->numIndexes; i++) { @@ -965,7 +1051,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; } } @@ -982,7 +1068,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; + hTonalMDCTConc->faded_signal_nrg_flt += mdctSpectrum[l] * mdctSpectrum[l]; } for (l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++) @@ -992,11 +1078,11 @@ void TonalMDCTConceal_InsertNoise( } } - if (hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG) + 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 - last_block_nrg_correct) / hTonalMDCTConc->faded_signal_nrg); + 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); } } @@ -1623,7 +1709,7 @@ void TonalMdctConceal_create_concealment_noise( } /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; + 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 */ @@ -1633,7 +1719,7 @@ void TonalMdctConceal_create_concealment_noise( *rnd_c = own_random(rnd_c); concealment_noise[i] = (c_inv * *rnd + c * *rnd_c) * noise_shape_buffer[i]; - hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[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 ) ) */ @@ -1645,7 +1731,7 @@ void TonalMdctConceal_create_concealment_noise( *rnd_c = own_random(rnd_c); concealment_noise[i] = (c_inv * *rnd + c * *rnd_c) * noise_shape_buffer[i]; - hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i]; + hTonalMDCTConc->curr_noise_nrg_flt += concealment_noise[i] * concealment_noise[i]; *rnd_c = own_random(rnd_c); } @@ -1683,7 +1769,7 @@ void TonalMdctConceal_whiten_noise_shape( push_wmops("apply_sns_on_noise_shape"); - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_flt[0]; psychParams = st->hTonalMDCTConc->psychParams; hFdCngCom = st->hFdCngDec->hFdCngCom; -- GitLab From 2683d182cb4bbfec156410ed44033711a863bf67 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 9 Jan 2024 19:19:43 +0530 Subject: [PATCH 2/2] Crash issue fix [x] Replaced addition and subtraction basops with saturation to handle overflow in filter_with_allpass function. --- lib_dec/ivas_stereo_esf_dec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_dec/ivas_stereo_esf_dec.c b/lib_dec/ivas_stereo_esf_dec.c index e4469c9f4..afe565cd3 100644 --- a/lib_dec/ivas_stereo_esf_dec.c +++ b/lib_dec/ivas_stereo_esf_dec.c @@ -175,11 +175,11 @@ void filter_with_allpass_fx( IF( pos == D3_upd ) D3_upd = -1; - P1_fx = L_sub( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); - P2_fx = L_sub( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); - P3_fx = L_add( D1_fx[pos], L_sub( Mpy_32_32( g1_fx, P2_fx ), Mpy_32_32( g2_fx, D2_fx[pos] ) ) ); - P4_fx = L_add( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); - P5_fx = L_add( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); + P1_fx = L_sub_sat( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); + P2_fx = L_sub_sat( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); + P3_fx = L_add_sat( D1_fx[pos], L_sub( Mpy_32_32( g1_fx, P2_fx ), Mpy_32_32( g2_fx, D2_fx[pos] ) ) ); + P4_fx = L_add_sat( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); + P5_fx = L_add_sat( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); out[k] = P5_fx; /* could overwrite sig */ D1_fx[( pos + d1 ) & mask] = P2_fx; -- GitLab