diff --git a/lib_com/options.h b/lib_com/options.h index cbc77b6e7057a8f879213759cebf40a567f7a2c6..63fe353e0c239049fa052cab8dfe90ae76eec6ec 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -99,4 +99,7 @@ #define TEST_HR #define REMOVE_EVS_DUPLICATES /* remove core-coder duplicated functions, ACELP low-band decoder */ +#define FIX_1348_BIT_PRECISION_IMPROVEMENT +#define FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD +//#define FIX_1348_BIT_PRECISION_IMPROVEMENT_ROUND_OLD_BUFF #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 86b5ec0b70dc62f4645763ea9e9f8cae0ff46b7b..3c07b814000003c47cdc437cf0cfa977aedbe46c 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -9909,6 +9909,9 @@ void IMDCT_ivas_fx( const Word16 frame_cnt, const Word16 bfi, Word16 *old_out_fx, +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Word16 *q_old_out_fx, +#endif const Word16 FB_flag, Decoder_State *st, const Word16 fullbandScale, @@ -10019,6 +10022,9 @@ void ivas_mdct_core_reconstruct_fx( /* o : synthesis @output_FS */ // e_sig Word16 fUseTns[CPE_CHANNELS][NB_DIV], /* i : flage TNS enabled */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + const Word16 isParamMC, +#endif Word16 q_x, Word16 e_sig[CPE_CHANNELS] ); diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index af80ee1f54e8672c19b05e6c29432d91639ccd3f..fc8fda9adf343396dbc2fc4e86089757e6d140bf 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -2601,6 +2601,9 @@ void IMDCT_ivas_fx( const Word16 frame_cnt, const Word16 bfi, Word16 *old_out_fx, // Q(-2) +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Word16 *q_old_out_fx, +#endif const Word16 FB_flag, Decoder_State *st, const Word16 fullbandScale, @@ -2862,9 +2865,16 @@ void IMDCT_ivas_fx( move16(); Word16 diff = sub( q_tmp_fx_32, q_win ); +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Word16 q_old_out_diff = sub( q_tmp_fx_32, *q_old_out_fx ); +#endif FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + old_out_fx_32[ind] = L_shl( old_out_fx[ind], q_old_out_diff ); +#else old_out_fx_32[ind] = L_shl( old_out_fx[ind], diff ); +#endif move32(); } @@ -2872,7 +2882,11 @@ void IMDCT_ivas_fx( FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], q_old_out_diff ) ); +#else old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], diff ) ); +#endif xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) ); move16(); move16(); @@ -2880,7 +2894,9 @@ void IMDCT_ivas_fx( } ELSE { +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD Word16 q_old_out = q_win; +#endif move16(); edct_fx( x_fx, xn_buf_fx_32 + add( shr( overlap, 1 ), nz ), L_frame, &q_xn_buf_fx_32 ); Word16 res_m, res_e; @@ -2904,15 +2920,26 @@ void IMDCT_ivas_fx( move16(); } +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, q_old_out_fx, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); +#else window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, &q_old_out, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); q_diff = sub( q_old_out, q_win ); +#endif Word16 diff = sub( q_tmp_fx_32, q_win ); FOR( Word16 ind = 0; ind < L_frame; ind++ ) { +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_ROUND_OLD_BUFF + old_out_fx[ind] = shr_r_sat( old_out_fx[ind], q_diff ); +#else old_out_fx[ind] = shr_sat( old_out_fx[ind], q_diff ); +#endif move16(); +#endif xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff ); move16(); } @@ -3004,9 +3031,18 @@ void IMDCT_ivas_fx( IF( hTcxCfg->last_aldo != 0 ) { +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Word16 tmp_old_out; + Word16 q_diff = sub( *q_old_out_fx, q_win ); +#endif FOR( i = 0; i < sub( overlap, tcx_mdct_window_min_length ); i++ ) { - xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], old_out_fx[( i + nz )] ); // Q(-2) +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + tmp_old_out = shr_sat( old_out_fx[( i + nz )], q_diff ); + xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], tmp_old_out ); // Q(-2) +#else + xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], old_out_fx[( i + nz )] ); // Q(-2) +#endif move16(); } @@ -3019,17 +3055,32 @@ void IMDCT_ivas_fx( // tested FOR( ; i < overlap; i++ ) /* perfectly reconstructing ALDO shortening */ { - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], old_out_fx[( i + nz )] ); // Q(-2) +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + tmp_old_out = shr_sat( old_out_fx[( i + nz )], q_diff ); + xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tmp_old_out ); // Q(-2) +#else + xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], old_out_fx[( i + nz )] ); // Q(-2) +#endif move16(); } FOR( i = 0; i < ( tcx_mdct_window_min_length / 2 ); i++ ) { - xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[i].v.re ) ); // Q(-2) +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + tmp_old_out = shr_sat( old_out_fx[( ( i + nz ) + overlap )], q_diff ); + xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( tmp_old_out, tcx_mdct_window_minimum_fx[i].v.re ) ); // Q(-2) +#else + xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[i].v.re ) ); // Q(-2) +#endif move16(); } FOR( ; i < tcx_mdct_window_min_length; i++ ) { +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + tmp_old_out = shr_sat( old_out_fx[( ( i + nz ) + overlap )], q_diff ); + xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( tmp_old_out, tcx_mdct_window_minimum_fx[( tcx_mdct_window_min_length - ( 1 + i ) )].v.im ) ); // Q(-2) +#else xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[( tcx_mdct_window_min_length - ( 1 + i ) )].v.im ) ); // Q(-2) +#endif move16(); } } @@ -3037,12 +3088,22 @@ void IMDCT_ivas_fx( { FOR( ; i < ( overlap - ( tcx_mdct_window_min_length / 2 ) ); i++ ) { - xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); // Q(-2) +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + tmp_old_out = shr_sat( old_out_fx[( i + nz )], q_diff ); + xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( tmp_old_out, tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); // Q(-2) +#else + xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); // Q(-2) +#endif move16(); } FOR( ; i < overlap; i++ ) { - xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); // Q(-2) +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + tmp_old_out = shr_sat( old_out_fx[( i + nz )], q_diff ); + xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( tmp_old_out, tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); // Q(-2) +#else + xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); // Q(-2) +#endif move16(); } } @@ -3091,7 +3152,9 @@ void IMDCT_ivas_fx( /* Compute windowed synthesis in case of switching to ALDO windows in next frame */ Copy( xn_buf_fx + sub( L_frame, nz ), old_out_fx, add( nz, overlap ) ); set16_fx( old_out_fx + add( nz, overlap ), 0, nz ); - +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + *q_old_out_fx = q_win; +#endif tcx_windowing_synthesis_past_frame( old_out_fx + nz, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_curr_overlap_mode ); /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */ @@ -3602,12 +3665,14 @@ void decoder_tcx_ivas_fx( Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( st->Q_syn, st->hTcxDec->Q_syn_Overl_TDAC ) ); // Scaling to Q_syn st->hTcxDec->Q_syn_Overl_TDAC = st->Q_syn; move16(); - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, negate( st->hHQ_core->Q_old_wtda ) ); // Scaling to Q_syn - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, negate( st->hHQ_core->Q_old_wtda_LB ) ); // Scaling to Q_syn +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, negate( st->hHQ_core->Q_old_wtda ) ); // Scaling to Q0 + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, negate( st->hHQ_core->Q_old_wtda_LB ) ); // Scaling to Q0 st->hHQ_core->Q_old_wtda = 0; move16(); st->hHQ_core->Q_old_wtda_LB = 0; move16(); +#endif Scale_sig( st->hTcxDec->old_syn_Overl, 320, st->Q_syn - st->hTcxDec->Q_old_syn_Overl ); // Scaling to Q_syn st->hTcxDec->Q_old_syn_Overl = st->Q_syn; @@ -3623,10 +3688,12 @@ void decoder_tcx_ivas_fx( Scale_sig( synth_fx, L_frame_glob, negate( st->Q_syn ) ); Scale_sig( synthFB_fx, L_frameTCX_glob, negate( st->Q_syn ) ); // Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, 1 ); +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD st->hHQ_core->Q_old_wtda = st->Q_syn; // Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, ( sub( st->hHQ_core->Q_old_wtda, st->Q_syn ) ) ); st->hHQ_core->Q_old_wtda_LB = st->Q_syn; // Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, ( sub( st->hHQ_core->Q_old_wtda, st->Q_syn ) ) ); +#endif Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 - st->hTcxDec->Q_old_syn_Overl ) ); // Scaling to Q-2 st->hTcxDec->Q_old_syn_Overl = -2; } @@ -5196,7 +5263,11 @@ void decoder_tcx_imdct_fx( IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, &st->hHQ_core->Q_old_wtda_LB, 0, st, 0, acelp_zir_fx, q_win ); +#else kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); +#endif } /* Generate additional comfort noise to mask potential coding artefacts */ @@ -5218,7 +5289,11 @@ void decoder_tcx_imdct_fx( Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, &st->hHQ_core->Q_old_wtda_LB, 0, st, 0, acelp_zir_fx, q_win ); +#else kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); +#endif } FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) @@ -5235,13 +5310,21 @@ void decoder_tcx_imdct_fx( { IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, 1, st, ratio, acelp_zir_fx, q_win ); +#else kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); +#endif } ELSE { IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, 1, st, ratio, acelp_zir_fx, q_win ); +#else kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); +#endif } FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) { diff --git a/lib_dec/ivas_core_dec_fx.c b/lib_dec/ivas_core_dec_fx.c index 38ec5b943407e373e2c2ad240e48d8987892cf30..6ca2982f5d4eed9ca2764bd886dcaca25285e6d2 100644 --- a/lib_dec/ivas_core_dec_fx.c +++ b/lib_dec/ivas_core_dec_fx.c @@ -576,14 +576,16 @@ ivas_error ivas_core_dec_fx( move32(); /* TCX decoder */ - Scale_sig( st->hPFstat->mem_stp, L_SUBFR, -Qsyn_temp ); // Q0 - Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, -Qsyn_temp ); // Q0 + Scale_sig( st->hPFstat->mem_stp, L_SUBFR, -Qsyn_temp ); // Q0 + Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, -Qsyn_temp ); // Q0 +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, -st->hHQ_core->Q_old_wtda_LB ); // Q0 Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, -st->hHQ_core->Q_old_wtda ); // Q0 st->hHQ_core->Q_old_wtda_LB = 0; move16(); st->hHQ_core->Q_old_wtda = 0; move16(); +#endif IF( st_ivas == NULL ) { diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index c10c6beda022acd7c4dbefdb47d957741647b4c4..dcec695f3de95ae39120bce8f99030a111afd2aa 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -132,7 +132,9 @@ ivas_error ivas_cpe_dec_fx( IF( hCPE->hCoreCoder[ind1]->hHQ_core ) { Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ind1]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ind1]->hHQ_core->Q_old_wtda_LB ) ); // Q11 +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT hCPE->hCoreCoder[ind1]->hHQ_core->q_old_outLB_fx = Q11; +#endif move16(); } } diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_jbm_dec_fx.c index 3f67962dc6f29e329016854e7d6b4cc09492b293..e313304e24a5728238c93c57b0bd91fdf7ce25cd 100644 --- a/lib_dec/ivas_jbm_dec_fx.c +++ b/lib_dec/ivas_jbm_dec_fx.c @@ -434,8 +434,13 @@ ivas_error ivas_jbm_dec_tc_fx( { Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB = q; + move16(); +#else hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); +#endif } IF( hCPE->hStereoDft != NULL ) { @@ -950,8 +955,13 @@ ivas_error ivas_jbm_dec_tc_fx( { Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, sub( q, hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); // q +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB = q; + move16(); +#else hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); +#endif } IF( hCPE->hStereoDft != NULL ) { @@ -996,7 +1006,6 @@ ivas_error ivas_jbm_dec_tc_fx( IF( hCPE->hCoreCoder[0] != NULL ) { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB, q ) ); // Q_old_wtda_LB Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, L_FRAME48k, sub( hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda, q ) ); // Q_old_wtda } @@ -1386,8 +1395,13 @@ ivas_error ivas_jbm_dec_tc_fx( { Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_LB_fx32, L_FRAME32k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ); // q Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->hHQ_core->old_out_fx, hCPE->hCoreCoder[0]->hHQ_core->old_out_fx32, L_FRAME48k, q - hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda ); // q +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + hCPE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB = q; + move16(); +#else hCPE->hCoreCoder[0]->hHQ_core->q_old_outLB_fx = q; move16(); +#endif } IF( hCPE->hStereoDft != NULL ) { diff --git a/lib_dec/ivas_mct_dec_fx.c b/lib_dec/ivas_mct_dec_fx.c index 32403b11a032c798ae52da7a70721396466c7f6f..058b57593d09014c722f70971e75e5efd604e0ac 100644 --- a/lib_dec/ivas_mct_dec_fx.c +++ b/lib_dec/ivas_mct_dec_fx.c @@ -346,7 +346,11 @@ ivas_error ivas_mct_dec_fx( } Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, add( M, 1 ), sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + ivas_mdct_core_reconstruct_fx( hCPE, x_fx, synth_fx, fUseTns[cpe_id], 1, st_ivas->mc_mode == MC_MODE_PARAMMC, q_output, e_sig ); +#else ivas_mdct_core_reconstruct_fx( hCPE, x_fx, synth_fx, fUseTns[cpe_id], 1, q_output, e_sig ); +#endif Word16 hdrm, sh; hdrm = getScaleFactor16( synth_fx[0], hCPE->hCoreCoder[0]->hTcxDec->L_frameTCX ); diff --git a/lib_dec/ivas_mdct_core_dec_fx.c b/lib_dec/ivas_mdct_core_dec_fx.c index fabebede4e6e468526331188d065f9086d1715c9..fc757feec79b3607638e25261b2ac04a241c5df0 100644 --- a/lib_dec/ivas_mdct_core_dec_fx.c +++ b/lib_dec/ivas_mdct_core_dec_fx.c @@ -1083,6 +1083,9 @@ void ivas_mdct_core_reconstruct_fx( /* o : synthesis @output_FS */ // e_sig Word16 fUseTns[CPE_CHANNELS][NB_DIV], /* i : flage TNS enabled */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + const Word16 isParamMC, +#endif Word16 q_x, Word16 e_sig[CPE_CHANNELS] ) { @@ -1098,7 +1101,11 @@ void ivas_mdct_core_reconstruct_fx( Word16 *synthFB_fx; Word16 q_syn = 0; move16(); +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + Word16 q_win = -1; +#else Word16 q_win = -2; +#endif move16(); /* TCX */ Word16 xn_buf_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; // Q(-2) @@ -1118,6 +1125,11 @@ void ivas_mdct_core_reconstruct_fx( bfi = sts[0]->bfi; move16(); +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + if ( isParamMC ) + q_win = -2; +#endif + /* TNS, ITF, IMDCT and updates */ FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -1172,10 +1184,16 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_syn_Overl_TDAC ) ); // st->hTcxDec->Q_syn_Overl_TDAC -> q_win Scale_sig( st->hTcxDec->old_syn_Overl, L_FRAME32k / 2, sub( q_win, st->hTcxDec->Q_old_syn_Overl ) ); // Q(-1 - st->Q_syn) -> q_win st->hTcxDec->Q_old_syn_Overl = q_win; - Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win + Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( q_win, st->Q_syn ) ); // Q(st->Q_syn) -> q_win + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( q_win, st->hHQ_core->Q_old_wtda_LB ) ); // Q(st->hHQ_core->Q_old_wtda_LB) -> q_win + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( q_win, st->hHQ_core->Q_old_wtda ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + st->hHQ_core->Q_old_wtda = q_win; + move16(); + st->hHQ_core->Q_old_wtda_LB = q_win; + move16(); +#endif Scale_sig( synth_buf_fx, add( add( st->hTcxDec->old_synth_len, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( synth_bufFB_fx, add( add( st->hTcxDec->old_synth_lenFB, L_FRAME_PLUS ), M ), sub( q_win, q_syn ) ); // q_syn -> q_win Scale_sig( st->syn, M + 1, sub( q_win, st->Q_syn ) ); // st->Q_syn -> q_win @@ -1206,6 +1224,10 @@ void ivas_mdct_core_reconstruct_fx( /* Note: these buffers are not subframe-based, hence no indexing with k */ set16_fx( &st->hHQ_core->old_out_LB_fx[0], 0, L_frame[ch] ); set16_fx( &st->hHQ_core->old_out_fx[0], 0, L_frameTCX[ch] ); +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD_NO + st->hHQ_core->Q_old_wtda = Q15; + st->hHQ_core->Q_old_wtda_LB = Q15; +#endif set16_fx( &st->hTcxDec->syn_Overl[0], 0, shr( L_frame[ch], 1 ) ); set16_fx( &st->hTcxDec->syn_OverlFB[0], 0, shr( L_frameTCX[ch], 1 ) ); set16_fx( &st->hTcxDec->syn_Overl_TDAC[0], 0, shr( L_frame[ch], 1 ) ); @@ -1246,12 +1268,17 @@ void ivas_mdct_core_reconstruct_fx( Scale_sig( st->syn, M + 1, add( st->Q_syn, 2 ) ); Scale_sig( st->hTcxDec->syn_OverlFB, L_FRAME_MAX / 2, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( st->Q_syn, q_win ) ); // q_win -> st->Q_syn st->hHQ_core->Q_old_wtda = st->Q_syn; move16(); st->hHQ_core->Q_old_wtda_LB = st->Q_syn; move16(); +#endif +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT_DYNAMIC_QOLD + Scale_sig( st->mem_syn2_fx, M, sub( negate( q_win ), 2 ) ); +#endif } ELSE /*ACELP core for ACELP-PLC */ { diff --git a/lib_dec/ivas_post_proc_fx.c b/lib_dec/ivas_post_proc_fx.c index c0e69b91663e2275b0398e4dec3439df3baf5c1b..b82cc1d00dc995c8144da9c704ad8b83240a7367 100644 --- a/lib_dec/ivas_post_proc_fx.c +++ b/lib_dec/ivas_post_proc_fx.c @@ -588,7 +588,11 @@ void stereo_dft_dec_core_switching_fx( Word32 tmp_fade_fx[max( STEREO_DFT_ALLPASS_FADELEN_12k8, STEREO_DFT_ALLPASS_FADELEN_16k )]; Copy32( st->hHQ_core->old_out_LB_fx32 + numZeros, hCPE->hStereoDft->ap_fade_mem_fx, ap_fade_len ); /*st->hHQ_core->q_old_outLB_fx*/ +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + hCPE->hStereoDft->q_ap_fade_mem_fx = st->hHQ_core->Q_old_wtda_LB; +#else hCPE->hStereoDft->q_ap_fade_mem_fx = st->hHQ_core->q_old_outLB_fx; +#endif move16(); test(); diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 890e5fc9ef6db902a60454e094612449ceac424c..fd9398769ab90bb6bc20aa2fa17cfe3a0add3bc1 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -550,7 +550,11 @@ void stereo_mdct_core_dec_fx( } Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[0]->old_Aq_12_8_fx, hCPE->hCoreCoder[0]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[0]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ Copy_Scale_sig_16_32_no_sat( hCPE->hCoreCoder[1]->old_Aq_12_8_fx, hCPE->hCoreCoder[1]->old_Aq_12_8_fx_32, M + 1, sub( 28, sub( 15, norm_s( sub( hCPE->hCoreCoder[1]->old_Aq_12_8_fx[0], 1 ) ) ) ) ); /* Q28 */ +#ifdef FIX_1348_BIT_PRECISION_IMPROVEMENT + ivas_mdct_core_reconstruct_fx( hCPE, x_fx, signal_outFB_tmp_fx, fUseTns, 0, st_ivas->mc_mode == MC_MODE_PARAMMC, Q11, e_sigFB ); +#else ivas_mdct_core_reconstruct_fx( hCPE, x_fx, signal_outFB_tmp_fx, fUseTns, 0, Q11, e_sigFB ); +#endif Copy32( signal_out_tmp_fx[0], signal_out_fx[0], L_FRAME48k ); /* Q11 */ Copy32( signal_out_tmp_fx[1], signal_out_fx[1], L_FRAME48k ); /* Q11 */ diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index fcd5142a4c11b824f0a9638e8ca0d1209ae58b37..9d6f4943626c9a0f77bf4c9461fbfa4715a9940b 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -698,11 +698,13 @@ typedef struct hq_nbfec_structure typedef struct hq_dec_structure { Word32 old_out_fx32[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ - Word16 old_out_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA */ + Word16 old_out_fx[L_FRAME48k]; /* HQ core - previous synthesis for OLA. Q_old_wtda */ Word16 exp_old_out; - Word16 old_out_LB_fx[L_FRAME32k]; /* HQ core - previous synthesis for OLA for Low Band */ + Word16 old_out_LB_fx[L_FRAME32k]; /* HQ core - previous synthesis for OLA for Low Band. Q_old_wtda_LB */ Word32 old_out_LB_fx32[L_FRAME32k]; +#ifndef FIX_1348_BIT_PRECISION_IMPROVEMENT Word16 q_old_outLB_fx; +#endif Word16 Q_old_wtda_LB; Word16 Q_old_wtda; Word16 Q_old_postdec; /*scaling of the output of core_switching_post_dec_fx() */