diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index c8ac7e4a2eaf3980d6acb2f6dfa8f0105a920d2b..733bb252a86533ba04ebd95652ad14646562ef9a 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1702,12 +1702,13 @@ ivas_error openCldfb_ivas_fx( move16(); } - IF ( ( hs->cldfb_state_fx = (Word16 *) malloc( buf_len * sizeof( Word16 ) ) ) == NULL ) + IF ( ( hs->cldfb_state_fx = (Word32 *) malloc( buf_len * sizeof( Word32 ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); } - set_s(hs->cldfb_state_fx, 0, buf_len); + hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer + set32_fx(hs->cldfb_state_fx, 0, buf_len); /* TODO: remove the floating point dependency */ diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index e1133b09cbf21c7ba7c698ca847775a71b8153dc..797dcd063212626353b42a7781f1bd09af2f27fd 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -3,7 +3,7 @@ #include #include "options.h" #include "prot.h" -Word32 floatToFixed(const float f, Word16 Q) +Word32 floatToFixed(float f, Word16 Q) { if (f == 1.0f && Q == Q15) return MAX16B; @@ -15,35 +15,35 @@ Word32 floatToFixed(const float f, Word16 Q) return (Word32)(f * (float)((unsigned int)1 << Q) + (f >= 0 ? 0.5 : -0.5)); } -float fixedToFloat(const Word32 i, Word16 Q) +float fixedToFloat(Word32 i, Word16 Q) { if (Q < 0) return (i * (float)(((unsigned)1) << (-Q))); else return (float)(i) / (float)((unsigned int)1 << Q); } -void floatToFixed_arrL(const float *f, Word32 *i, Word16 Q, Word16 l) +void floatToFixed_arrL(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) +void floatToFixed_arr(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) +void fixedToFloat_arrL(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) +void fixedToFloat_arr(Word16 *i, float *f, Word16 Q, Word16 l) { for (int j = 0; j < l; j++) { diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 5aa7794b15bce1b71a4ebd4bc566c701a982e981..77c228a28e8eaabce130c2becf58c56b1132c0c4 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3620,6 +3620,15 @@ void ivas_init_dec_get_num_cldfb_instances( int16_t *numCldfbAnalyses, /* o : number of CLDFB analysis instances */ int16_t *numCldfbSyntheses /* o : number of CLDFB synthesis instances */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_cldfb_dec_reconfig_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const Word16 nchan_transport_old, /* i : number of TCs in previous frame */ + Word16 numCldfbAnalyses_old, /* i : number of CLDFB analysis instances in previous frame */ + const Word16 numCldfbSyntheses_old, /* i : number of CLDFB synthesis instances in previous frame */ + const Word16 Q_cldfbSynDec +); +#endif // IVAS_FLOAT_FIXED ivas_error ivas_cldfb_dec_reconfig( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -4502,6 +4511,12 @@ void ivas_itda( const int16_t length ); +void ivas_spar_get_cldfb_gains_fx( + SPAR_DEC_HANDLE hSpar, + HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, + HANDLE_CLDFB_FILTER_BANK cldfbSynDec0, + const DECODER_CONFIG_HANDLE hDecoderConfig +); void ivas_spar_get_cldfb_gains( SPAR_DEC_HANDLE hSpar, HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index d8712d00172eb37b02a14d42f0e81d95ef6d7aa2..11e4691b63443658a2b0c1e7fb06ec240671b0eb 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -800,6 +800,10 @@ typedef struct ivas_fb_mixer_state_structure int16_t prior_input_length; int16_t windowed_fr_offset; float cldfb_cross_fade[CLDFB_NO_COL_MAX]; +#ifdef IVAS_FLOAT_FIXED + const Word16 *pFilterbank_cross_fade_fx; + Word16 cldfb_cross_fade_fx[CLDFB_NO_COL_MAX]; +#endif // IVAS_FLOAT_FIXED int16_t cldfb_cross_fade_start; int16_t cldfb_cross_fade_end; diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index e960f09751c8e0e6706988fcbed0902b7dcd3009..9f1e971f93d0f29358e1c46199f30d9e9c426fb5 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -71,17 +71,17 @@ 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); +void floatToFixed_arrL( float * f, Word32* i, Word16 Q, Word16 l); +void floatToFixed_arr( float * f, Word16* i, Word16 Q, Word16 l); +void fixedToFloat_arrL( Word32 *i, float * f, Word16 Q, Word16 l); +void fixedToFloat_arr( Word16 *i, float * f, Word16 Q, Word16 l); Word16 Q_factor(float x); Word16 Q_factor_L(float 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 floatToFixed( float f, Word16 Q); +float fixedToFloat( Word32 i, Word16 Q); // Float to 32-bit Mantissa and Exponent using frexp void f2me(float n, Word32 *mantissa, Word16 *expo); diff --git a/lib_dec/ACcontextMapping_dec_fx.c b/lib_dec/ACcontextMapping_dec_fx.c index 51f778c255e085897e7ed43817f2b81a0d29f0e7..10b177c9f92f68341a490c9df27f70973daff6d1 100644 --- a/lib_dec/ACcontextMapping_dec_fx.c +++ b/lib_dec/ACcontextMapping_dec_fx.c @@ -585,7 +585,7 @@ Word16 RCcontextMapping_decode2_no_mem_s17_LCS_fx( /* Main Loop through the 2-tuples */ FOR( k = 0; k < lastnz; k += 2 ) { - rateQ = add( rateFlag, GT_16( k, ( nt_half ) ) ); + rateQ = add( rateFlag, (Word16)GT_16( k, ( nt_half ) ) ); /* BER detection: Check max value of context t leading to out-of-bound access to ari_lookup_s17_LC[]*/ IF( ( GE_16( t, ( 1 << ( NBITS_CONTEXT ) ) ) ) || lsbs_bit_pos <= 0 ) diff --git a/lib_dec/core_dec_switch_fx.c b/lib_dec/core_dec_switch_fx.c index 19d85c467599ed7c7bde18780cfccfe005ada5ca..a8923e07dccbc1236fa98c8df06a5d3155a81fe8 100644 --- a/lib_dec/core_dec_switch_fx.c +++ b/lib_dec/core_dec_switch_fx.c @@ -390,7 +390,7 @@ void mode_switch_decoder_LPD_ivas_fx( { InitTnsConfigs( bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFDec->infoIGFStopFreq, total_brate, st->element_mode, MCT_flag ); - SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, EQ_16(st->element_mode , IVAS_CPE_MDCT) ); + SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, (Word8)EQ_16(st->element_mode , IVAS_CPE_MDCT) ); } } diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index b8bd80bad4b455b84632f42f7e9d5a33d0bd0080..dcab83e68e92ab83128a55d8941743cc0718853b 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -35,6 +35,7 @@ #include "ivas_prot.h" #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" +#include "prot_fx2.h" #endif // IVAS_FLOAT_FIXED #include "prot.h" #include @@ -461,6 +462,90 @@ ivas_error ivas_hp20_dec_reconfig( * * Allocate, initialize, and configure CLDFB handles in case of bitrate switching *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_cldfb_dec_reconfig_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const Word16 nchan_transport_old, /* i : number of TCs in previous frame */ + Word16 numCldfbAnalyses_old, /* i : number of CLDFB analysis instances in previous frame */ + const Word16 numCldfbSyntheses_old, /* i : number of CLDFB synthesis instances in previous frame */ + const Word16 Q_cldfbSynDec ) +{ + Word16 i, numCldfbAnalyses, numCldfbSyntheses; + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; + + hDecoderConfig = st_ivas->hDecoderConfig; + + ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses ); + + /* special case, if there was one transport channel in the previous frame and more than one in the current frame, + remove the second CLDFB here, it was for CNA/CNG */ + IF ( EQ_16(st_ivas->ivas_format , SBA_FORMAT) && EQ_16(nchan_transport_old , 1) && EQ_16(numCldfbAnalyses_old , 2) && GT_16(st_ivas->nchan_transport , 1) ) + { + deleteCldfb_ivas( &( st_ivas->cldfbAnaDec[1] ) ); + numCldfbAnalyses_old--; + } + /* resample CLDFB analysis instances */ + FOR( i = 0; i < min( numCldfbAnalyses, numCldfbAnalyses_old ); i++ ) + { + IF( EQ_32( L_mult0( L_mult0( st_ivas->cldfbAnaDec[i]->no_channels, st_ivas->cldfbAnaDec[i]->no_col ), FRAMES_PER_SEC ), hDecoderConfig->output_Fs ) ) + { + resampleCldfb_ivas_fx( st_ivas->cldfbAnaDec[i], hDecoderConfig->output_Fs ); + } + } + + /* Analysis*/ + IF ( GT_16(numCldfbAnalyses_old , numCldfbAnalyses) ) + { + /* delete superfluous CLDFB synthesis instances */ + FOR ( i = numCldfbAnalyses; i < numCldfbAnalyses_old; i++ ) + { + deleteCldfb_ivas( &( st_ivas->cldfbAnaDec[i] ) ); + } + } + ELSE IF ( LT_16(numCldfbAnalyses_old , numCldfbAnalyses) ) + { + /* create additional CLDFB synthesis instances */ + FOR ( i = numCldfbAnalyses_old; i < numCldfbAnalyses; i++ ) + { + IF ( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + /* Synthesis */ + IF ( GT_16(numCldfbSyntheses_old , numCldfbSyntheses) ) + { + /* delete superfluous CLDFB synthesis instances */ + FOR ( i = numCldfbSyntheses; i < numCldfbSyntheses_old; i++ ) + { + deleteCldfb_ivas( &( st_ivas->cldfbSynDec[i] ) ); + } + } + ELSE IF ( LT_16(numCldfbSyntheses_old , numCldfbSyntheses) ) + { + /* create additional CLDFB synthesis instances */ + FOR ( i = numCldfbSyntheses_old; i < numCldfbSyntheses; i++ ) + { + IF ( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + /* CLDFB Interpolation weights */ + IF ( EQ_16(st_ivas->ivas_format , SBA_FORMAT) && ( NE_16(numCldfbAnalyses_old , numCldfbAnalyses) || NE_16(numCldfbSyntheses_old , numCldfbSyntheses) || NE_16(nchan_transport_old , st_ivas->nchan_transport) ) && NE_16(numCldfbAnalyses , 0) && NE_16(numCldfbSyntheses , 0) ) + { + ivas_spar_get_cldfb_gains_fx( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); + FOR( i = 0; i < st_ivas->cldfbAnaDec[0]->cldfb_state_length; i++ ) + st_ivas->cldfbAnaDec[0]->cldfb_state_fx[i] = L_shr( st_ivas->cldfbAnaDec[0]->cldfb_state_fx[i], 16 ); // Scaling down from 27 to 11 + FOR( i = 0; i < st_ivas->cldfbSynDec[0]->cldfb_state_length; i++ ) + st_ivas->cldfbSynDec[0]->cldfb_state_fx[i] = L_shr( st_ivas->cldfbSynDec[0]->cldfb_state_fx[i], 21- Q_cldfbSynDec); // Scaling down from 21 to Q_cldfbSynDec + } + return IVAS_ERR_OK; +} +#endif // IVAS_FLOAT_FIXED ivas_error ivas_cldfb_dec_reconfig( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index c60b3e63dca52e3b713f43aeb9db7948d57d89c7..373d006105c08835965b9655e34d3ff9a3d54bc0 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -204,9 +204,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( Word16 num_src; FOR( Word16 i = 0; i < 4; i++ ) { - directivity_fx[i * 3] = floatToFixed( st_ivas->hRenderConfig->directivity[i * 3], 6 ); - directivity_fx[i * 3 + 1] = floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 1], 6 ); - directivity_fx[i * 3 + 2] = floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 2], 15 ); + directivity_fx[i * 3] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3], 6 ); + directivity_fx[i * 3 + 1] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 1], 6 ); + directivity_fx[i * 3 + 2] = (Word16)floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 2], 15 ); } #endif IF ( ( error = ivas_td_binaural_open_fx( st_ivas , SrcInd,&num_src, directivity_fx) ) != IVAS_ERR_OK ) @@ -424,10 +424,46 @@ static ivas_error ivas_ism_bitrate_switching_dec( * CLDFB instances *-----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +#if 1 /*Cleanup changes: float to fixed*/ + Word16 i, Q_weights, Q_cldfbSynDec = 21; + FOR( i = 0; i < 16; i++ ) + { + IF( st_ivas->cldfbAnaDec[i] ) + floatToFixed_arrL( st_ivas->cldfbAnaDec[i]->cldfb_state, st_ivas->cldfbAnaDec[i]->cldfb_state_fx, 11, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + IF ( st_ivas->hSpar ) + { + Q_weights = Q_factor_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, 16 ); + floatToFixed_arr( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, Q_weights, 16 ); + } + IF( st_ivas->cldfbSynDec[0] ) + { + Q_cldfbSynDec = s_min( Q_cldfbSynDec, Q_factor_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ) ); + floatToFixed_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } +#endif + IF ( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, nchan_transport_old, numCldfbAnalyses_old, numCldfbSyntheses_old ,Q_cldfbSynDec) ) != IVAS_ERR_OK ) + { + return error; + } +#if 1 /*CCleanup changes:fixed to float changes*/ + FOR( i = 0; i < 16; i++ ) + { + IF( st_ivas->cldfbAnaDec[i] ) + fixedToFloat_arrL( st_ivas->cldfbAnaDec[i]->cldfb_state_fx, st_ivas->cldfbAnaDec[i]->cldfb_state, 11, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } + IF( st_ivas->cldfbSynDec[0] ) + { + fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + } +#endif +#else if ( ( error = ivas_cldfb_dec_reconfig( st_ivas, nchan_transport_old, numCldfbAnalyses_old, numCldfbSyntheses_old ) ) != IVAS_ERR_OK ) { return error; } +#endif // IVAS_FOAT_FIXED /*-----------------------------------------------------------------* * floating-point output audio buffers diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 17b883148ec9ceccd5df96b5a64b0da3b3034d34..bef6921816d7666f4201a109b838196bf8b3ad8b 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -532,6 +532,14 @@ static int16_t ivas_parse_spar_header( return bwidth; } +#ifdef IVAS_FLOAT_FIXED +static Word16 get_random_number_fx( + Word16 *seed ) +{ + Word16 x = own_random2_fx( *seed ); + return x; +} +#endif // IVAS_FLOAT_FIXED static float get_random_number( int16_t *seed ) @@ -693,6 +701,168 @@ static void matrix_inverse( * * *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_spar_get_cldfb_gains_fx( + SPAR_DEC_HANDLE hSpar, + HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0, + HANDLE_CLDFB_FILTER_BANK cldfbSynDec0, + const DECODER_CONFIG_HANDLE hDecoderConfig ) +{ + Word32 output_Fs_fx = hDecoderConfig->output_Fs; + Word16 *weights_fx; + Word16 cf_start_s_fx, cf_len_s_fx; + Word32 T_fx[3 * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX - CLDFB_NO_CHANNELS_MAX][3]; + Word32 Tt_T_fx[3][3]; + Word32 Tt_T_inv_fx[3][3]; + Word32 Tt_tgt_fx[3]; + Word32 ts_inout_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 ts_re_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 ts_im_fx[CLDFB_NO_CHANNELS_MAX]; + Word32 *pp_ts_im_fx[1], *pp_ts_re_fx[1]; + Word32 tgt_fx[( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX]; + Word16 pt_len, stride, num_cldfb_bands, decfb_delay; + Word16 encfb_delay, cf_start, cf_end, cf_len; + Word16 ts, cf_cldfb_start, cf_cldfb_end; + Word16 sample, num_cf_slots, num_samples; + Word16 seed, split_band, slot_row, slot_col, slot, tmp_idx; + + pt_len = cldfbAnaDec0->p_filter_length; + num_cldfb_bands = cldfbAnaDec0->no_channels; + + stride = NS2SA_fx2( output_Fs_fx, DELAY_CLDFB_NS ); + encfb_delay = NS2SA_fx2( output_Fs_fx, IVAS_FB_ENC_DELAY_NS ); + decfb_delay = NS2SA_fx2( output_Fs_fx, IVAS_FB_DEC_DELAY_NS ); + + cf_start = add( sub( hSpar->hFbMixer->cross_fade_start_offset, encfb_delay ), decfb_delay ); /* time domain after CLDFB synthesis*/ + cf_end = add( sub( hSpar->hFbMixer->cross_fade_end_offset, encfb_delay ), decfb_delay ); + cf_len = sub( cf_end, cf_start ); + weights_fx = hSpar->hFbMixer->cldfb_cross_fade_fx; + cf_cldfb_start = shr( (Word16) ceil_fixed( sub( divide1616( sub( cf_start, shr( decfb_delay, 1 ) ), shl( stride, 9 ) ), 32 ), 6 ), 6 ); + cf_cldfb_end = shr( divide1616( add( sub( cf_start, shr( decfb_delay, 1 ) ), cf_len ), shl( stride, 9 ) ), 6 ); /*q-factor of stride is 9(as max value is 60)*/ + num_cf_slots = add( sub( cf_cldfb_end, cf_cldfb_start ), 1 ); + num_samples = add( imult1616( num_cf_slots, stride ), sub( pt_len, stride ) ); + seed = RANDOM_INITSEED; + split_band = SPAR_DIRAC_SPLIT_START_BAND; + pp_ts_im_fx[0] = ts_im_fx; + pp_ts_re_fx[0] = ts_re_fx; + set32_fx( tgt_fx, 0, ( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX ); + cf_start_s_fx = divide3232( ( sub( cf_start, shr( decfb_delay, 1 ) ) ), output_Fs_fx ); + cf_len_s_fx = divide3232( sub( hSpar->hFbMixer->cross_fade_end_offset, hSpar->hFbMixer->cross_fade_start_offset ), output_Fs_fx ); + Word16 Q_cf_start_s = norm_s( cf_start_s_fx ) - 1; + Word16 Q_cf_len_s = norm_s( cf_len_s_fx ); + Word16 Q_weights = 15 + Q_cf_start_s - Q_cf_len_s; + FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ ) + { + weights_fx[ts] = divide1616( shl( sub( divide3232( L_mult0( add( shl( ts, 1 ), 1 ), shr( stride, 1 ) ), output_Fs_fx ), cf_start_s_fx ), Q_cf_start_s ), shl( cf_len_s_fx, Q_cf_len_s ) ); + weights_fx[ts] = s_max( s_min( weights_fx[ts], shl( 1, Q_weights ) ), 0 ); + } + hSpar->hFbMixer->cldfb_cross_fade_start = cf_cldfb_start; + hSpar->hFbMixer->cldfb_cross_fade_end = cf_cldfb_end; + + IF( GT_16( num_cf_slots, 3 ) || GT_16( pt_len, 10 * CLDFB_NO_CHANNELS_MAX ) || GT_16( stride, CLDFB_NO_CHANNELS_MAX ) || EQ_16( split_band, IVAS_MAX_NUM_BANDS ) ) + { + return; + } + + /* optimization*/ + /* compute time-domain cross-fade for considered time slots*/ + tmp_idx = sub( cf_start, imult1616( cf_cldfb_start, stride ) ); + Word32 pFilterbank_cross_fade_fx[192];// Temporarily added to stored fixed value of hSpar->hFbMixer->pFilterbank_cross_fade_fx + floatToFixed_arrL( hSpar->hFbMixer->pFilterbank_cross_fade, pFilterbank_cross_fade_fx, 31, cf_len ); + FOR( sample = 0; sample < cf_len; sample++ ) + { + tgt_fx[tmp_idx++] = pFilterbank_cross_fade_fx[sample]; + /* increasing window function */ + } + FOR( ; tmp_idx < num_samples; tmp_idx++ ) + { + /* fill up with ones*/ + tgt_fx[tmp_idx] = MAX_32; + } + FOR( sample = 0; sample < num_samples; sample++ ) + { + /* initialize trasnform matrix with zeros*/ + T_fx[sample][0] = T_fx[sample][1] = T_fx[sample][2] = 0; + } + + FOR( sample = 0; sample < pt_len - stride; sample++ ) + { + /* fill internal CLDFB analysis time buffer with data*/ + Word16 x_fx = get_random_number_fx( &seed ); + cldfbAnaDec0->cldfb_state_fx[sample] = L_shl(x_fx,12); + } + Word16 q_cldfb = 27; + FOR( slot = 0; slot < num_cf_slots; slot++ ) + { + FOR( sample = 0; sample < stride; sample++ ) + { + Word16 x_fx = get_random_number_fx( &seed ); + ts_inout_fx[sample] = L_shl( x_fx, 12 );/*Q-27*/ + } + + 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 ); + cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, cldfbSynDec0 ); + + FOR( sample = 0; sample < stride; sample++ ) + { + T_fx[slot * stride + sample][slot] = ts_inout_fx[sample]; + } + tmp_idx = sub( pt_len, 1 ); + FOR( sample = stride; sample < pt_len; sample++ ) + { + T_fx[add( imult1616( slot, stride ), sample )][slot] = cldfbSynDec0->cldfb_state_fx[tmp_idx--]; + } + } + + /* target is synthesis output times the cross-fade window*/ + FOR( sample = 0; sample < num_samples; sample++ ) + { + tgt_fx[sample] = Mult_32_32( tgt_fx[sample], L_add( T_fx[sample][0], L_add( T_fx[sample][1], T_fx[sample][2] ) ) ); + } + /* compute matrices */ + FOR ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) + { + FOR ( slot_col = slot_row; slot_col < num_cf_slots; slot_col++ ) + { + Tt_T_fx[slot_row][slot_col] = 0; + FOR ( sample = 0; sample < num_samples; sample++ ) + { + Tt_T_fx[slot_row][slot_col] =L_add( Tt_T_fx[slot_row][slot_col], Mult_32_32(T_fx[sample][slot_row],T_fx[sample][slot_col] ) ); + } + } + } + + Tt_T_fx[1][0] = Tt_T_fx[0][1]; + Tt_T_fx[2][0] = Tt_T_fx[0][2]; + Tt_T_fx[2][1] = Tt_T_fx[1][2]; + FOR ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) + { + Tt_tgt_fx[slot_row] = 0; + FOR ( sample = 0; sample < num_samples; sample++ ) + { + Tt_tgt_fx[slot_row] = L_add(Tt_tgt_fx[slot_row],Mult_32_32(T_fx[sample][slot_row] , tgt_fx[sample])); + } + } + Word16 output_q = 0; + matrix_inverse_fx( Tt_T_fx, Tt_T_inv_fx, num_cf_slots, &output_q ); + /* compute the optimal coefficients */ + FOR ( slot_row = 0; slot_row < num_cf_slots; slot_row++ ) + { + Word32 tmp = 0; + FOR ( slot_col = 0; slot_col < num_cf_slots; slot_col++ ) + { + tmp = L_add(tmp,Mult_32_32(Tt_T_inv_fx[slot_row][slot_col] , Tt_tgt_fx[slot_col])); + } + weights_fx[add(cf_cldfb_start , slot_row)] = s_max( s_min( (Word16)tmp, (1<< (output_q-20)) ), 0 ); + } + + cldfb_reset_memory_fx( cldfbSynDec0 ); + cldfb_reset_memory_fx( cldfbAnaDec0 ); + + return; +} +#endif // IVAS_FLOAT_FIXED void ivas_spar_get_cldfb_gains( SPAR_DEC_HANDLE hSpar, diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index 48ff4486db0e668307d2d47cea739a617e70a468..3e431e2006a54769c936e4ef7fd179e4e48109d6 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -1157,10 +1157,10 @@ static void dec_prm_tcx_ivas_fx( floatToFixed_arr( st->mem_syn2, st->mem_syn2_fx, Q_mem_syn2, M ); FOR( i = 0; i < M; i++ ) { - st->mem_MA_fx[i] = (Word16) floatToFixed( st->mem_MA[i] * 2.56, 0 ); - st->mem_AR_fx[i] = (Word16) floatToFixed( st->mem_AR[i] * 2.56, 0 ); - st->lsf_old_fx[i] = (Word16) floatToFixed( st->lsf_old[i] * 2.56, 0 ); - st->lsfold_uw[i] = (Word16) floatToFixed( st->lsfold_uw_float[i] * 2.56, 0 ); + st->mem_MA_fx[i] = (Word16) floatToFixed( (float)(st->mem_MA[i] * 2.56), 0 ); + st->mem_AR_fx[i] = (Word16) floatToFixed((float)(st->mem_AR[i] * 2.56), 0 ); + st->lsf_old_fx[i] = (Word16) floatToFixed((float)(st->lsf_old[i] * 2.56), 0 ); + st->lsfold_uw[i] = (Word16) floatToFixed((float)(st->lsfold_uw_float[i] * 2.56), 0 ); } IF( st->hTcxCfg ) { @@ -1281,9 +1281,9 @@ static void dec_prm_tcx_ivas_fx( st->hTcxDec->LastFrameLevel_bfi_fx = (Word16) floatToFixed( st->hTcxDec->LastFrameLevel_bfi, 15 ); FOR( i = 0; i < PLC_MIN_STAT_BUFF_SIZE; i++ ) { - st->hTcxDec->NoiseLevelMemory_bfi_fx[i] = floatToFixed( st->hTcxDec->NoiseLevelMemory_bfi[i], 15 ); + st->hTcxDec->NoiseLevelMemory_bfi_fx[i] = (Word16)floatToFixed( st->hTcxDec->NoiseLevelMemory_bfi[i], 15 ); } - st->hTcxDec->cummulative_damping_tcx = floatToFixed( st->hTcxDec->cummulative_damping_tcx_float, 15 ); + st->hTcxDec->cummulative_damping_tcx = (Word16)floatToFixed( st->hTcxDec->cummulative_damping_tcx_float, 15 ); } IF ( st->hHQ_core ) { @@ -1330,7 +1330,7 @@ static void dec_prm_tcx_ivas_fx( floatToFixed_arr( st->hPFstat->mem_stp_flt, st->hPFstat->mem_stp, Q_mem_stp, L_SUBFR ); floatToFixed_arr( st->hPFstat->mem_pf_in_flt, st->hPFstat->mem_pf_in, Q_mem_pf_in, L_SUBFR ); floatToFixed_arr( st->hPFstat->mem_res2_flt, st->hPFstat->mem_res2, Q_mem_res2, DECMEM_RES2 ); - st->hPFstat->gain_prec = floatToFixed( st->hPFstat->gain_prec_flt, 14 ); // 1.f + st->hPFstat->gain_prec = (Word16)floatToFixed( st->hPFstat->gain_prec_flt, 14 ); // 1.f } Word16 Q_lsf_cng = Q_factor( 6400 ); floatToFixed_arr( st->lsf_cng_float, st->lsf_cng, Q_lsf_cng, M ); @@ -1419,7 +1419,7 @@ static void dec_prm_tcx_ivas_fx( Q_loBuffer = Q_factor_arr( st->hTECDec->loBuffer_flt, MAX_TEC_SMOOTHING_DEG ); floatToFixed_arr( st->hTECDec->loBuffer_flt, st->hTECDec->loBuffer, Q_loBuffer, MAX_TEC_SMOOTHING_DEG ); } - st->TcxBandwidth = floatToFixed( st->TcxBandwidth_float, 15 ); + st->TcxBandwidth = (Word16)floatToFixed( st->TcxBandwidth_float, 15 ); #endif // Float to fixed conversions end here Word16 start_bit_pos, bits_common; CONTEXT_HM_CONFIG hm_cfg;