diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index c6864bc05137ce5ffab8383029152b79dff1bfa3..e1133b09cbf21c7ba7c698ca847775a71b8153dc 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -12,7 +12,7 @@ Word32 floatToFixed(const float f, Word16 Q) if (Q < 0) return (Word32)((float)(f) / (float)(((unsigned)1) << (-Q)) + (f >= 0 ? 0.5 : -0.5)); else - return (Word32)(f * (float)(((unsigned)1) << Q) + (f >= 0 ? 0.5 : -0.5)); + return (Word32)(f * (float)((unsigned int)1 << Q) + (f >= 0 ? 0.5 : -0.5)); } float fixedToFloat(const Word32 i, Word16 Q) @@ -20,7 +20,7 @@ float fixedToFloat(const Word32 i, Word16 Q) if (Q < 0) return (i * (float)(((unsigned)1) << (-Q))); else - return (float)(i) / (float)(((unsigned)1) << Q); + return (float)(i) / (float)((unsigned int)1 << Q); } void floatToFixed_arrL(const float *f, Word32 *i, Word16 Q, Word16 l) { diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 33e301c827ed580aa0431546a4bbd0635e939e17..88901949aee1fe519e89e880a002c9f60f746a44 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -801,6 +801,7 @@ enum fea_names #define STEREO_L_TCA_OVLP_NS 5000000L /* overlap length of the ICA gain scaling */ +#define STEREO_DMX_GAIN_Q13 29066 /* calculated this -->"powf( 10, ( ( 1 << STEREO_BITS_TCA_GD ) - 1 ) * STEREO_TCA_GDSTEP + STEREO_TCA_GDMIN )"*/ /*----------------------------------------------------------------------------------* * TD Stereo Constants *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index d0ddaeccdba90dea0a80c6e71748840262bc64b2..ce448c5759eb749a99f4ac3d5b6681e13cd7c47b 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -989,4 +989,105 @@ Word16 matrix_product_diag_fx( const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ Word32 *Z, /* o : resulting matrix after the matrix multiplication */ Word16 *Z_e ); + + +// ivas_stereo_mdct_core_dec_fx.c +void stereo_mdct_core_dec_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + float *signal_out[CPE_CHANNELS], /* o : synthesis @internal_FS */ + float signal_outFB[CPE_CHANNELS][L_FRAME48k] /* o : synthesis @output_FS */ +); + +// ivas_stereo_mdct_stereo_com.c +void splitAvailableBits_fx( + const Word16 total_bits, /* i : total available bits for TCX coding */ + const Word16 split_ratio, /* i : split ratio */ + const Word16 isSBAStereoMode, /* i : signal core coding for SBA */ + Word16 *bits_ch0, /* o : bits for channel 0 */ + Word16 *bits_ch1 /* o : bits for channel 1 */ +); + +void stereo_tcx_init_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + const Word16 last_element_mode /* i : element mode of previous frame */ +); + +void initMdctStereoDecData_fx( + STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */ + const Word16 igf, /* i : flag indicating IGF activity */ + const H_IGF_GRID igfGrid, /* i : IGF grid configuration */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 bwidth /* i : audio bandwidth */ +); + +void stereo_mdct_init_bands_fx( + const Word16 L_frame, /* i : frame length */ + const Word16 tmp_tcx_mode, /* i : tcx mode (TCX10, TCX 20), -1 if transition frame */ + const Word32 element_brate, /* i : element bitrate */ + const Word16 igf, /* i : flag indicating if IGF is used */ + const H_IGF_GRID hIgfGrid, /* i : IGF grid setup */ + Word16 *sfbOffset, /* o : sfb offset table */ + Word16 *sfbCnt /* o : number of sfbs */ +); + +void stereo_mdct_init_igf_start_band_fx( + STEREO_MDCT_BAND_PARAMETERS *stbParams, /* i/o: stereo frequency band parameters */ + const Word16 transFac, /* i : transform factor */ + const Word16 bwidth, /* i : audio bandwidth */ + const Word32 element_brate /* i : element bitrate */ +); + +void ivas_mdct_dec_side_bits_frame_channel_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word16 param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ + Word16 p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ + Decoder_State *st0, /* i : pointer to bitstream handle */ + Word16 nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ + Word16 param[CPE_CHANNELS][DEC_NPRM_DIV * NB_DIV], /* i/o: parameters buffer */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + const Word16 odd_channel_cpe /* i : flag cpe with odd nb of tc channels */ +); + +void mdct_read_IGF_bits_fx( + Decoder_State *st, /* i/o: Decoder state handle */ + Decoder_State *st0 /* i : pointer to handle where bitstream is read */ +); + +void IGFDecReadData_ivas_fx( const IGF_DEC_INSTANCE_HANDLE hInstance, /**< in: | instance handle of IGF Deccoder */ + Decoder_State *st, /**< in: | decoder state */ + const Word16 igfGridIdx, /**< in: Q0 | in case of CELP->TCX switching, use 1.25 framelength */ + const Word16 isIndepFrame /**< in: Q0 | if 1: arith dec force reset, if 0: no reset */ +); + +void stereo_tca_init_dec_fx( + STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle for Fixed */ +); + +void stereo_icBWE_init_dec_fx( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ +); + +void stereo_icBWE_decproc_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *output[CPE_CHANNELS], /* i/o: output synthesis */ + Word32 outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ + const int16_t last_core, /* i : last core, primary channel */ + const int16_t last_bwidth, /* i : last bandwidth */ + const int16_t output_frame /* i : frame length */ +); + +void add_HB_to_mono_dmx_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 output[L_FRAME48k], /* i/o: output synthesis */ + Word32 outputHB[L_FRAME48k], /* i : HB synthesis */ + const int16_t last_core, /* i : last core, primary channel */ + const int16_t output_frame /* i : frame length */ +); + +void stereo_dft_dmx_out_reset_fx( + STEREO_DFT_DMX_DATA_HANDLE hStereoDftDmx /* i/o: DFT stereo DMX decoder */ +); + #endif diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index e5e27e8ad1367e932ada507a1adc9a6ee2cb560c..a781eab62b72e0d03cca769e47f821ba23cc588a 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -916,59 +916,6 @@ Word16 matrix_diag_product_fx( } #endif -/*---------------------------------------------------------------------* - * diag_matrix_product() - * - * compute the matrix product of a diagonal matrix X with a full matrix Y (Z=diag(Y)*X) - *---------------------------------------------------------------------*/ - -/*! r: success or failure */ -int16_t diag_matrix_product( - const float *Y, /* i : left hand diagonal matrix as vector containing the diagonal elements */ - const int16_t entriesY, /* i : length of the diagonal of the left hand matrix */ - const float *X, /* i : right hand matrix */ - const int16_t rowsX, /* i : number of rows of the right hand matrix */ - const int16_t colsX, /* i : number of columns of the right hand matrix */ - const int16_t transpX, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ - float *Z /* o : resulting matrix after the matrix multiplication */ -) -{ - int16_t i, j; - float *Zp = Z; - - /* Processing */ - if ( transpX == 1 ) /* We use X transpose */ - { - if ( colsX != entriesY ) - { - return EXIT_FAILURE; - } - for ( i = 0; i < rowsX; ++i ) - { - for ( j = 0; j < entriesY; ++j ) - { - *( Zp++ ) = X[i + j * rowsX] * Y[j]; - } - } - } - else /* Regular case */ - { - if ( rowsX != entriesY ) - { - return EXIT_FAILURE; - } - for ( i = 0; i < colsX; ++i ) - { - for ( j = 0; j < entriesY; ++j ) - { - *( Zp++ ) = *( X++ ) * Y[j]; - } - } - } - - return EXIT_SUCCESS; -} - #ifdef IVAS_FLOAT_FIXED Word16 diag_matrix_product_fx( const Word32 *Y, /* i : left hand diagonal matrix as vector containing the diagonal elements */ @@ -1026,95 +973,52 @@ Word16 diag_matrix_product_fx( /*---------------------------------------------------------------------* - * matrix_product_diag() + * diag_matrix_product() * - * compute only the main diagonal of X*Y (Z=diag(X*Y)) + * compute the matrix product of a diagonal matrix X with a full matrix Y (Z=diag(Y)*X) *---------------------------------------------------------------------*/ /*! r: success or failure */ -int16_t matrix_product_diag( - const float *X, /* i : left hand matrix */ - const int16_t rowsX, /* i : number of rows of the left hand matrix */ - const int16_t colsX, /* i : number of columns of the left hand matrix */ - const int16_t transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication */ - const float *Y, /* i : right hand matrix */ - const int16_t rowsY, /* i : number of rows of the right hand matrix */ - const int16_t colsY, /* i : number of columns of the right hand matrix */ - const int16_t transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ - float *Z /* o : resulting matrix after the matrix multiplication */ +int16_t diag_matrix_product( + const float *Y, /* i : left hand diagonal matrix as vector containing the diagonal elements */ + const int16_t entriesY, /* i : length of the diagonal of the left hand matrix */ + const float *X, /* i : right hand matrix */ + const int16_t rowsX, /* i : number of rows of the right hand matrix */ + const int16_t colsX, /* i : number of columns of the right hand matrix */ + const int16_t transpX, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ + float *Z /* o : resulting matrix after the matrix multiplication */ ) { - int16_t j, k; + int16_t i, j; float *Zp = Z; /* Processing */ - if ( transpX == 1 && transpY == 0 ) /* We use X transpose */ - { - if ( rowsX != rowsY ) - { - return EXIT_FAILURE; - } - - for ( j = 0; j < colsY; ++j ) - { - ( *Zp ) = 0.0f; - for ( k = 0; k < rowsX; ++k ) - { - ( *Zp ) += X[k + j * rowsX] * Y[k + j * rowsY]; - } - Zp++; - } - } - else if ( transpX == 0 && transpY == 1 ) /* We use Y transpose */ - { - if ( colsX != colsY ) - { - return EXIT_FAILURE; - } - for ( j = 0; j < rowsY; ++j ) - { - ( *Zp ) = 0.0f; - for ( k = 0; k < colsX; ++k ) - { - ( *Zp ) += X[j + k * rowsX] * Y[j + k * rowsY]; - } - Zp++; - } - } - else if ( transpX == 1 && transpY == 1 ) /* We use both transpose */ + if ( transpX == 1 ) /* We use X transpose */ { - if ( rowsX != colsY ) + if ( colsX != entriesY ) { return EXIT_FAILURE; } - - for ( j = 0; j < rowsY; ++j ) + for ( i = 0; i < rowsX; ++i ) { - - ( *Zp ) = 0.0f; - for ( k = 0; k < colsX; ++k ) + for ( j = 0; j < entriesY; ++j ) { - ( *Zp ) += X[k + j * rowsX] * Y[j + k * rowsY]; + *( Zp++ ) = X[i + j * rowsX] * Y[j]; } - - Zp++; } } else /* Regular case */ { - if ( colsX != rowsY ) + if ( rowsX != entriesY ) { return EXIT_FAILURE; } - - for ( j = 0; j < colsY; ++j ) + for ( i = 0; i < colsX; ++i ) { - ( *Zp ) = 0.0f; - for ( k = 0; k < colsX; ++k ) + for ( j = 0; j < entriesY; ++j ) { - ( *Zp ) += X[j + k * rowsX] * Y[k + j * rowsY]; + *( Zp++ ) = *( X++ ) * Y[j]; } - Zp++; } } @@ -1220,12 +1124,101 @@ Word16 matrix_product_diag_fx( #endif /*---------------------------------------------------------------------* - * cmplx_matrix_square() + * matrix_product_diag() * - * compute the square of a complex matrix (Z=X*X) + * compute only the main diagonal of X*Y (Z=diag(X*Y)) *---------------------------------------------------------------------*/ /*! r: success or failure */ +int16_t matrix_product_diag( + const float *X, /* i : left hand matrix */ + const int16_t rowsX, /* i : number of rows of the left hand matrix */ + const int16_t colsX, /* i : number of columns of the left hand matrix */ + const int16_t transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication */ + const float *Y, /* i : right hand matrix */ + const int16_t rowsY, /* i : number of rows of the right hand matrix */ + const int16_t colsY, /* i : number of columns of the right hand matrix */ + const int16_t transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ + float *Z /* o : resulting matrix after the matrix multiplication */ +) +{ + int16_t j, k; + float *Zp = Z; + + /* Processing */ + if ( transpX == 1 && transpY == 0 ) /* We use X transpose */ + { + if ( rowsX != rowsY ) + { + return EXIT_FAILURE; + } + + for ( j = 0; j < colsY; ++j ) + { + ( *Zp ) = 0.0f; + for ( k = 0; k < rowsX; ++k ) + { + ( *Zp ) += X[k + j * rowsX] * Y[k + j * rowsY]; + } + Zp++; + } + } + else if ( transpX == 0 && transpY == 1 ) /* We use Y transpose */ + { + if ( colsX != colsY ) + { + return EXIT_FAILURE; + } + for ( j = 0; j < rowsY; ++j ) + { + ( *Zp ) = 0.0f; + for ( k = 0; k < colsX; ++k ) + { + ( *Zp ) += X[j + k * rowsX] * Y[j + k * rowsY]; + } + Zp++; + } + } + else if ( transpX == 1 && transpY == 1 ) /* We use both transpose */ + { + if ( rowsX != colsY ) + { + return EXIT_FAILURE; + } + + for ( j = 0; j < rowsY; ++j ) + { + + ( *Zp ) = 0.0f; + for ( k = 0; k < colsX; ++k ) + { + ( *Zp ) += X[k + j * rowsX] * Y[j + k * rowsY]; + } + + Zp++; + } + } + else /* Regular case */ + { + if ( colsX != rowsY ) + { + return EXIT_FAILURE; + } + + for ( j = 0; j < colsY; ++j ) + { + ( *Zp ) = 0.0f; + for ( k = 0; k < colsX; ++k ) + { + ( *Zp ) += X[j + k * rowsX] * Y[k + j * rowsY]; + } + Zp++; + } + } + + return EXIT_SUCCESS; +} + #ifdef IVAS_FLOAT_FIXED void cmplx_matrix_square_fx( const Word32 *realX, /* i : real part of the matrix */ @@ -1291,6 +1284,14 @@ void cmplx_matrix_square_fx( } #endif + +/*---------------------------------------------------------------------* + * cmplx_matrix_square() + * + * compute the square of a complex matrix (Z=X*X) + *---------------------------------------------------------------------*/ + +/*! r: success or failure */ void cmplx_matrix_square( const float *realX, /* i : real part of the matrix */ const float *imagX, /* i : imaginary part of the matrix */ diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index fc3da15ba33d830beefa0b853156a0b9f654d60e..2d5fe1b63920eedba3ca7380c891110424a1cdfd 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -558,7 +558,40 @@ ivas_error ivas_cpe_dec_fx( * IC-BWE: output LB and HB mix in ACELP mode *----------------------------------------------------------------*/ - stereo_icBWE_decproc( hCPE, output_flt, outputHB, last_core, last_bwidth, output_frame ); +#ifdef IVAS_FLOAT_FIXED + Word32 *output_fx[CPE_CHANNELS]; + Word32 outputHB_fx[CPE_CHANNELS][L_FRAME48k]; + Word16 q_output_HB = 11; + FOR(Word16 j = 0; j < CPE_CHANNELS; j++) + { + output_fx[j] = (Word32 *)malloc(output_frame * sizeof(Word32)); + floatToFixed_arrL(output_flt[j], output_fx[j], *q_output, output_frame); + floatToFixed_arrL(outputHB[j], outputHB_fx[j], *q_output, output_frame); + } + + IF (hCPE->hStereoDft != NULL) + { + Word16 q_td_gain = Q_factor_arr(hCPE->hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX); + floatToFixed_arrL(hCPE->hStereoDft->td_gain, hCPE->hStereoDft->td_gain_fx, q_td_gain, STEREO_DFT_CORE_HIST_MAX); // Checking this. + } + + stereo_icBWE_decproc_fx(hCPE, output_fx, outputHB_fx, last_core, last_bwidth, output_frame); + + IF (hCPE->hStereoDft != NULL) + { + Word16 q_td_gain = Q_factor_arr(hCPE->hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX); + fixedToFloat_arrL(hCPE->hStereoDft->td_gain_fx, hCPE->hStereoDft->td_gain, q_td_gain, STEREO_DFT_CORE_HIST_MAX); // Checking this. + } + + FOR(Word16 j = 0; j < CPE_CHANNELS; j++) + { + fixedToFloat_arrL(output_fx[j], output_flt[j], q_output_HB, output_frame); + fixedToFloat_arrL(outputHB_fx[j], outputHB[j], q_output_HB, output_frame); + free(output_fx[j]); + } +#else + stereo_icBWE_decproc(hCPE, output_flt, outputHB, last_core, last_bwidth, output_frame); +#endif smooth_dft2td_transition( hCPE, output_flt, output_frame ); @@ -566,7 +599,7 @@ ivas_error ivas_cpe_dec_fx( * Temporal ICA, stereo adjustment and upmix *----------------------------------------------------------------*/ - stereo_tca_dec( hCPE, output_flt, output_frame ); + stereo_tca_dec(hCPE, output_flt, output_frame); /*----------------------------------------------------------------* * Common Stereo updates @@ -872,7 +905,11 @@ ivas_error create_cpe_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo DFT mono output\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + stereo_dft_dmx_out_reset_fx(hCPE->hStereoDftDmx); +#else stereo_dft_dmx_out_reset( hCPE->hStereoDftDmx ); +#endif } /*-----------------------------------------------------------------* @@ -886,7 +923,11 @@ ivas_error create_cpe_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo TCA\n" ) ); } - stereo_tca_init_dec( hCPE->hStereoTCA ); +#ifdef IVAS_FLOAT_FIXED + stereo_tca_init_dec_fx(hCPE->hStereoTCA); +#else + stereo_tca_init_dec(hCPE->hStereoTCA); +#endif } /*-----------------------------------------------------------------* @@ -900,7 +941,13 @@ ivas_error create_cpe_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE\n" ) ); } - stereo_icBWE_init_dec( hCPE->hStereoICBWE ); + //stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx(hCPE->hStereoICBWE); +#else + stereo_icBWE_init_dec(hCPE->hStereoICBWE); +#endif + } /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 66d3e576fe1f611dfda1ff6e1caa206d877be71c..9a5a2b630d9ba85d921297fac0872825ea9ae6db 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -100,11 +100,11 @@ typedef struct stereo_dft_dec_data_struct #endif - int16_t dft32ms_ovl; /* Overlap size */ - const float *win32ms; /* DFT window */ - const float *win32ms_12k8; /* DFT window */ - const float *win32ms_16k; /* DFT window */ - const float *win32ms_8k; /* DFT window */ + int16_t dft32ms_ovl; /* Overlap size */ + const float *win32ms; /* DFT window */ + const float *win32ms_12k8; /* DFT window */ + const float *win32ms_16k; /* DFT window */ + const float *win32ms_8k; /* DFT window */ #ifdef IVAS_FLOAT_FIXED const Word16 *win32ms_fx; /* DFT window */ const Word16 *win32ms_12k8_fx; /* DFT window */ @@ -124,7 +124,7 @@ typedef struct stereo_dft_dec_data_struct const Word16 *win232ms_8k_fx; /* DFT window */ #endif - const float *win_8k; /* DFT window residual */ + const float *win_8k; /* DFT window residual */ /*Bands*/ int16_t band_res[STEREO_DFT_DEC_DFT_NB]; @@ -145,6 +145,9 @@ typedef struct stereo_dft_dec_data_struct int16_t no_ipd_flag; /* flag to indicate when no IPD gets used */ float itd[STEREO_DFT_DEC_DFT_NB]; +#ifdef IVAS_FLOAT_FIXED + Word16 itd_fx[STEREO_DFT_DEC_DFT_NB]; +#endif float itd_xfade_step; float itd_xfade_target; @@ -222,6 +225,10 @@ typedef struct stereo_dft_dec_data_struct float hb_nrg[STEREO_DFT_CORE_HIST_MAX]; float hb_nrg_subr[STEREO_DFT_NBDIV]; float td_gain[STEREO_DFT_CORE_HIST_MAX]; +#ifdef IVAS_FLOAT_FIXED + Word32 td_gain_fx[STEREO_DFT_CORE_HIST_MAX]; + Word32 hb_stefi_sig_fx[L_FRAME48k + NS2SA(48000, STEREO_DFT_TD_STEFI_DELAY_NS)]; +#endif /* stereo DTX */ float g_state[STEREO_DFT_BAND_MAX]; @@ -254,11 +261,18 @@ typedef struct stereo_dft_dec_data_struct /* DFT Stereo mono output structure */ typedef struct stereo_dft_dmx_out_data_structure { - float targetGain; /* TCA gain norm applied on target (or right) channel in current frame */ + float targetGain; /* TCA gain norm applied on target (or right) channel in current frame */ float prevTargetGain; /* TCA gain norm applied on target (or right) channel in previous frame */ - +#ifdef IVAS_FLOAT_FIXED + Word32 targetGain_fx; + Word32 prevTargetGain_fx; +#endif float memOutHB[NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; float memTransitionHB[NS2SA( 48000, STEREO_DFT32MS_OVL_NS )]; +#ifdef IVAS_FLOAT_FIXED + Word32 memOutHB_fx[NS2SA(48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS)]; + Word32 memTransitionHB_fx[NS2SA(48000, STEREO_DFT32MS_OVL_NS)]; +#endif } STEREO_DFT_DMX_DATA, *STEREO_DFT_DMX_DATA_HANDLE; @@ -308,18 +322,18 @@ typedef struct stereo_td_dec_data_structure int16_t tdm_SM_flag; /* current channel combination scheme flag */ int16_t tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ - int16_t tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ - int16_t tdm_low_rate_mode; /* secondary channel low rate mode flag */ + int16_t tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ + int16_t tdm_low_rate_mode; /* secondary channel low rate mode flag */ float tdm_Pri_pitch_buf[NB_SUBFR]; int16_t tdm_Pitch_reuse_flag; int16_t tdm_LRTD_flag; - int16_t flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ + int16_t flag_skip_DMX; /* flag that indicates whether the TD downmixing is skipped */ float TCX_old_syn_Overl[L_FRAME16k / 2]; /* past ovrl buffer for possible switching from TD stereo ACELP to MDCT stereo TCX frame */ - float prevSP_ratio; /* previous SP ratio */ - float SP_ratio_LT; /* longterm SP ratio */ - float c_LR_LT; /* left-right cross-correlation */ + float prevSP_ratio; /* previous SP ratio */ + float SP_ratio_LT; /* longterm SP ratio */ + float c_LR_LT; /* left-right cross-correlation */ } STEREO_TD_DEC_DATA, *STEREO_TD_DEC_DATA_HANDLE; @@ -340,7 +354,7 @@ typedef struct stereo_mdct_dec_data_structure int16_t global_ild[2]; /* Quantized ILD for the whole spectrum */ int16_t split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ - int16_t IGFStereoMode[2]; /* MDCT stereo mode for IGF */ + int16_t IGFStereoMode[2]; /* MDCT stereo mode for IGF */ int16_t use_itd; int16_t itd_mode; /*0/1*/ @@ -370,21 +384,29 @@ typedef struct stereo_mdct_dec_data_structure typedef struct stereo_tca_dec_data_structure { - int16_t refChanIndx; /* reference channel index in current frame */ - int16_t prevRefChanIndx; /* reference channel index in previous frame */ - int16_t indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ - int16_t indx_ica_gD; /* ICA target gain */ - float targetGain; /* gain norm applied on target (or right) channel in current frame */ - float prevTargetGain; /* gain norm applied on target (or right) channel in previous frame */ + int16_t refChanIndx; /* reference channel index in current frame */ + int16_t prevRefChanIndx; /* reference channel index in previous frame */ + int16_t indx_ica_NCShift; /* ICA target channel inter-channel corrstats */ + int16_t indx_ica_gD; /* ICA target gain */ + float targetGain; /* gain norm applied on target (or right) channel in current frame */ +#ifdef IVAS_FLOAT_FIXED + Word16 targetGain_fx; // Q14 + Word16 prevTargetGain_fx; // Q14 +#endif + float prevTargetGain; /* gain norm applied on target (or right) channel in previous frame */ - int16_t corrLagStats; /* corr lag stats in current frame */ - int16_t prevCorrLagStats; /* corr lag stats in previous frame */ + int16_t corrLagStats; /* corr lag stats in current frame */ + int16_t prevCorrLagStats; /* corr lag stats in previous frame */ int16_t interp_dec_prevNCShift; /* NC Shift in previous frame */ int16_t interp_dec_switch_to_zero_diff; /* switch flag for interpolation */ - float memChanL[L_DEC_MEM_LEN_ICA]; /* left channel input to correct at the cross-over */ - float memChanR[L_DEC_MEM_LEN_ICA]; /* right channel input to correct at the cross-over */ + float memChanL[L_DEC_MEM_LEN_ICA]; /* left channel input to correct at the cross-over */ +#ifdef IVAS_FLOAT_FIXED + Word32 memChanL_fx[L_DEC_MEM_LEN_ICA]; /* left channel input to correct at the cross-over for Fixed */ + Word32 memChanR_fx[L_DEC_MEM_LEN_ICA]; /* right channel input to correct at the cross-over for Fixed */ +#endif + float memChanR[L_DEC_MEM_LEN_ICA]; /* right channel input to correct at the cross-over */ } STEREO_TCA_DEC_DATA, *STEREO_TCA_DEC_HANDLE; @@ -405,14 +427,29 @@ typedef struct stereo_icbwe_dec_data_structure float memTransitionHB[CPE_CHANNELS][NS2SA( 48000, STEREO_DFT32MS_OVL_NS )]; +#ifdef IVAS_FLOAT_FIXED + Word32 memOutHB_fx[CPE_CHANNELS][NS2SA(48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS)]; + Word32 memTransitionHB_fx[CPE_CHANNELS][NS2SA(48000, STEREO_DFT32MS_OVL_NS)]; +#endif /* unscaled & scaled SHB synthesis memory */ float mem_syn_shb_nonref[L_SHB_LAHEAD]; float mem_lpc_shbsynth_nonref[LPC_SHB_ORDER]; float mem_syn_shb_ola_nonref[L_SHB_LAHEAD]; +#ifdef IVAS_FLOAT_FIXED + /* unscaled & scaled SHB synthesis memory */ + Word32 mem_syn_shb_nonref_fx[L_SHB_LAHEAD]; + Word32 mem_lpc_shbsynth_nonref_fx[LPC_SHB_ORDER]; // Q10 + Word32 mem_syn_shb_ola_nonref_fx[L_SHB_LAHEAD]; +#endif /* inter-channel BWE spectral shape adj. */ float prevSpecMapping; float memShbSpecMapping; +#ifdef IVAS_FLOAT_FIXED + Word32 prevSpecMapping_fx; + Word32 prevgsMapping_fx; + Word32 memShbSpecMapping_fx; // Q24 +#endif float prevgsMapping; float memShbHilbert_nonref[HILBERT_MEM_SIZE]; @@ -420,6 +457,13 @@ typedef struct stereo_icbwe_dec_data_structure float memShb_fsout_nonref[INTERP_3_2_MEM_LEN]; int16_t syn_dm_phase_nonref; +#ifdef IVAS_FLOAT_FIXED + Word32 memShbHilbert_nonref_fx[HILBERT_MEM_SIZE]; + Word32 memShbInterp_nonref_fx[2 * ALLPASSSECTIONS_STEEP + 1]; + Word32 memShb_fsout_nonref_fx[INTERP_3_2_MEM_LEN]; + Word32 icbweM2Ref_prev_fx; +#endif + float icbweM2Ref_prev; float nlExc16k[L_FRAME16k]; @@ -511,7 +555,7 @@ typedef struct dirac_output_synthesis_cov_state_structure float *diffuse_power_factor; /* only pointer to local buffers */ - float *direct_responses; /* direct responses for DOA of current frame. Size: num_freq_bands*num_channels. */ + float *direct_responses; /* direct responses for DOA of current frame. Size: num_freq_bands*num_channels. */ float *direct_responses_square; float *diffuse_responses_square; /* squared diffuse responses. Size: num_channels. */ @@ -773,8 +817,8 @@ typedef struct cpe_dec_data_structure int32_t element_brate; /* CPE element total bitrate in bps */ int32_t last_element_brate; /* last CPE element total bitrate in bps */ - int16_t element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ - int16_t last_element_mode; /* last element mode */ + int16_t element_mode; /* element mode, in CPE it can be IVAS_CPE_DFT, IVAS_CPE_TD or IVAS_CPE_MDCT */ + int16_t last_element_mode; /* last element mode */ int16_t stereo_switching_counter; int16_t NbFrameMod; @@ -792,7 +836,7 @@ typedef struct cpe_dec_data_structure STEREO_ICBWE_DEC_HANDLE hStereoICBWE; /* Stereo inter-channel BWE data handle */ STEREO_CNG_DEC_HANDLE hStereoCng; /* Stereo CNG data structure */ - int16_t nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ + int16_t nchan_out; /* number of output channels (1: mono dmx, 2: default stereo) */ float prev_hb_synth[CPE_CHANNELS][NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; float prev_synth[CPE_CHANNELS][NS2SA( 48000, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS )]; @@ -846,7 +890,7 @@ typedef struct mct_dec_block_data_struct typedef struct mct_dec_data_structure { - int16_t nchan_out_woLFE; /* number of active channels within multi-channel configuration */ + int16_t nchan_out_woLFE; /* number of active channels within multi-channel configuration */ int16_t currBlockDataCnt; int16_t bitsChannelPairIndex; /* bits needed to code channel pair index, depends on number of active channels */ MCT_DEC_BLOCK_DATA_HANDLE hBlockData[MCT_MAX_BLOCKS]; @@ -1101,7 +1145,7 @@ typedef struct decoder_config_structure int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ IVAS_RENDER_FRAMESIZE render_framesize; - int16_t Opt_delay_comp; /* flag indicating delay compensation active */ + int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index f5cf35c98c0d80b6f14f19b7e943bc8dbe97252c..d209df818092d579dffeb2baeaa8caaff4d40e98 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -529,6 +529,11 @@ void stereo_dft_dec_reset( set_zero( hStereoDft->hb_nrg, STEREO_DFT_CORE_HIST_MAX ); set_zero( hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); +#ifdef IVAS_FLOAT_FIXED + set32_fx(hStereoDft->hb_stefi_sig_fx, 0, L_FRAME48k + NS2SA(48000, STEREO_DFT_TD_STEFI_DELAY_NS)); + set32_fx(hStereoDft->td_gain_fx, 0, STEREO_DFT_CORE_HIST_MAX); +#endif + /* PLC parameters */ set_zero( hStereoDft->res_mem, STEREO_DFT_RES_BW_MAX ); hStereoDft->time_offs = 0; diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx.c index 0d3053e1d50b32233e1a7a714a0c5a756e9e0755..5275db19d4ca595a048151702f37ace9122c3043 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx.c @@ -44,6 +44,8 @@ #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" +#include "prot_fx2.h" +#include "prot_fx1.h" #endif @@ -66,6 +68,28 @@ void stereo_dft_dmx_out_reset( return; } +#ifdef IVAS_FLOAT_FIXED +void stereo_dft_dmx_out_reset_fx( + STEREO_DFT_DMX_DATA_HANDLE hStereoDftDmx /* i/o: DFT stereo DMX decoder */ +) +{ +#if 1 /*TODO: Remove float dft_dmx_reset*/ + hStereoDftDmx->targetGain = 1.0f; + hStereoDftDmx->prevTargetGain = 1.0f; +#endif + hStereoDftDmx->targetGain_fx = ONE_IN_Q29; + hStereoDftDmx->prevTargetGain_fx = ONE_IN_Q29; + +#if 1 /*TODO: Remove float dft_dmx_reset*/ + set_zero(hStereoDftDmx->memOutHB, NS2SA(48000, STEREO_DFT32MS_OVL_NS)); + set_zero(hStereoDftDmx->memTransitionHB, NS2SA(48000, STEREO_DFT32MS_OVL_NS)); +#endif + set32_fx(hStereoDftDmx->memOutHB_fx, 0, NS2SA(48000, STEREO_DFT32MS_OVL_NS)); + set32_fx(hStereoDftDmx->memTransitionHB_fx, 0, NS2SA(48000, STEREO_DFT32MS_OVL_NS)); + + return; +} +#endif /*------------------------------------------------------------------------- * stereo_dft_unify_dmx() @@ -344,3 +368,117 @@ void add_HB_to_mono_dmx( return; } + +#ifdef IVAS_FLOAT_FIXED +void add_HB_to_mono_dmx_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 output[L_FRAME48k], /* i/o: output synthesis */ + Word32 outputHB[L_FRAME48k], /* i : HB synthesis */ + const int16_t last_core, /* i : last core, primary channel */ + const int16_t output_frame /* i : frame length */ +) +{ + int16_t i, j, decoderDelay, icbweOLASize, dftOvlLen, memOffset; + Word32 temp_fx[L_FRAME48k + NS2SA(48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS)]; + + Word32 winSlope_fx = 0; + Word32 alpha_fx; + const Word32 *win_dft_fx; + int32_t output_Fs; + Word32 *memOutHB_fx, *memTransitionHB_fx; + + output_Fs = hCPE->hCoreCoder[0]->output_Fs; + Word16 q_memOutHB = Q_factor_arr(hCPE->hStereoDftDmx->memOutHB, NS2SA(48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS)); + floatToFixed_arrL(hCPE->hStereoDftDmx->memOutHB, hCPE->hStereoDftDmx->memOutHB_fx, q_memOutHB, NS2SA(48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS)); + memOutHB_fx = hCPE->hStereoDftDmx->memOutHB_fx; + Word16 q_memTransitionHB = Q_factor_arr(hCPE->hStereoDftDmx->memTransitionHB, NS2SA(48000, STEREO_DFT32MS_OVL_NS)); + floatToFixed_arrL(hCPE->hStereoDftDmx->memTransitionHB, hCPE->hStereoDftDmx->memTransitionHB_fx, q_memTransitionHB, NS2SA(48000, STEREO_DFT32MS_OVL_NS)); + memTransitionHB_fx = hCPE->hStereoDftDmx->memTransitionHB_fx; + + memOffset = NS2SA(output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS); + + IF (EQ_16(hCPE->hCoreCoder[0]->core, ACELP_CORE) && GT_32(hCPE->hCoreCoder[0]->extl_brate, 0)) + { + /* Resampled LB and HB offset */ + Copy32(outputHB, temp_fx + memOffset, output_frame - memOffset); + + decoderDelay = NS2SA(output_Fs, IVAS_DEC_DELAY_NS); + + IF (NE_16(last_core, ACELP_CORE)) + { + /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ + icbweOLASize = NS2SA(output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS); + + FOR (i = 0; i < decoderDelay; i++) + { + temp_fx[i] = 0; + } + + assert(icbweOLASize > 0); + switch (output_Fs) + { + case 48000: + winSlope_fx = 17895698; //Q30 + break; + case 32000: + winSlope_fx = 26843546; + break; + case 16000: + winSlope_fx = 53687092; + break; + } + alpha_fx = winSlope_fx; // Q30 + FOR (; i < decoderDelay + icbweOLASize; i++) + { + temp_fx[i] = L_shl(Mpy_32_32(temp_fx[i], alpha_fx), 1); + alpha_fx = L_add_sat(alpha_fx, winSlope_fx); + } + } + ELSE + { + Copy32(memOutHB_fx, temp_fx, memOffset); + } + + v_add_32(temp_fx, output, output, output_frame); + + Copy32(outputHB + output_frame - memOffset, memOutHB_fx, memOffset); + + win_dft_fx = (Word32 *)hCPE->hStereoDft->win32ms_fx; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + + /* Preparing buffers in anticipation of an ACELP to TCX switch */ + j = 0; + FOR (i = 0; i < memOffset; i++) + { + memTransitionHB_fx[i] = memOutHB_fx[i] * win_dft_fx[STEREO_DFT32MS_STEP * (dftOvlLen - 1 - j)]; + j++; + } + + FOR (i = 0; j < dftOvlLen; i++) + { + memTransitionHB_fx[memOffset + i] = outputHB[output_frame - i - 1] * win_dft_fx[STEREO_DFT32MS_STEP * (dftOvlLen - 1 - j)]; + j++; + } + } + ELSE + { + IF (EQ_16(last_core, ACELP_CORE)) + { + /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ + IF (EQ_16(hCPE->element_mode, IVAS_CPE_DFT) && EQ_16(hCPE->nchan_out, 1) && EQ_16(hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF)) + { + v_add_32(output, outputHB, output, NS2SA(output_Fs, STEREO_DFT32MS_OVL_NS)); + } + ELSE + { + v_add_32(output, memTransitionHB_fx, output, NS2SA(output_Fs, STEREO_DFT32MS_OVL_NS)); + } + + set32_fx(memOutHB_fx, 0, memOffset); + set32_fx(memTransitionHB_fx, 0, NS2SA(output_Fs, STEREO_DFT32MS_OVL_NS)); + } + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec.c index 760d81ce6eedffc3a5d64cab30f669ee4ef42ca9..6fa4c2a533db6e33b1b30f8ba8de3645c0b3a7be 100644 --- a/lib_dec/ivas_stereo_ica_dec.c +++ b/lib_dec/ivas_stereo_ica_dec.c @@ -41,6 +41,10 @@ #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" +#include "prot_fx2.h" +#include "ivas_prot_fx.h" +#include "basop32.h" +#include "ivas_stat_dec.h" /*--------------------------------------------------------------- @@ -355,3 +359,36 @@ void stereo_tca_init_dec( return; } + +#ifdef IVAS_FLOAT_FIXED +void stereo_tca_init_dec_fx( + STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle */ +) +{ + hStereoTCA->refChanIndx = L_CH_INDX; + hStereoTCA->prevRefChanIndx = L_CH_INDX; + hStereoTCA->indx_ica_NCShift = 0; + hStereoTCA->indx_ica_gD = 0; + hStereoTCA->targetGain = 1.0f; /* TODO: Remove float init*/ + hStereoTCA->targetGain_fx = ONE_IN_Q14; + hStereoTCA->prevTargetGain_fx = ONE_IN_Q14; + hStereoTCA->prevTargetGain = 1.0f; /* TODO: Remove float init*/ + + hStereoTCA->corrLagStats = 0; + hStereoTCA->prevCorrLagStats = 0; + + hStereoTCA->interp_dec_prevNCShift = 0; + hStereoTCA->interp_dec_switch_to_zero_diff = 0; + +#if 1 + set_f( hStereoTCA->memChanL, 0.0f, L_DEC_MEM_LEN_ICA ); /*TODO: Remove float init*/ + set_f(hStereoTCA->memChanR, 0.0f, L_DEC_MEM_LEN_ICA); /* TODO: Remove float init*/ +#endif + + set32_fx( hStereoTCA->memChanL_fx, 0, L_DEC_MEM_LEN_ICA ); + set32_fx( hStereoTCA->memChanR_fx, 0, L_DEC_MEM_LEN_ICA ); + + + return; +} +#endif diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 37f4afa15f74216ce5f0044e4429872a5cfcaa3d..a751cd3a1cd76c1ad30f965fbe0158a1199495e5 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -38,9 +38,12 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" +#include "prot_fx2.h" +#include "prot_fx1.h" /*-------------------------------------------------------------------* * ic_bwe_dec_reset() @@ -68,6 +71,51 @@ static void ic_bwe_dec_reset( return; } +/*-------------------------------------------------------------------* + * ic_bwe_dec_reset_fx() + * + * core switching reset of IC BWE memory + *-------------------------------------------------------------------*/ + +#ifdef IVAS_FLOAT_FIXED +static void ic_bwe_dec_reset_fx( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo ICBWE handle */ +) +{ + /* unscaled & scaled SHB synthesis memory */ +#if 1 /*TODO: remove the float reset later*/ + set_f( hStereoICBWE->mem_syn_shb_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + set_f( hStereoICBWE->mem_lpc_shbsynth_nonref, 0, LPC_SHB_ORDER ); + set_f( hStereoICBWE->mem_syn_shb_ola_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ +#endif + + /* unscaled & scaled SHB synthesis memory */ + set32_fx( hStereoICBWE->mem_syn_shb_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ // Q9 or Q15 + set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); + set32_fx( hStereoICBWE->mem_syn_shb_ola_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + + /* inter-channel BWE SP and GSP mem reset */ +#if 1 /*TODO: remove float reset later*/ + hStereoICBWE->memShbSpecMapping = 0; +#endif + + hStereoICBWE->memShbSpecMapping_fx = 0; // Q24 : max value 66.61324 + +#if 1 /*TODO: remove float reset later*/ + set_f( hStereoICBWE->memShbHilbert_nonref, 0, HILBERT_MEM_SIZE ); + set_f( hStereoICBWE->memShbInterp_nonref, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set_f( hStereoICBWE->memShb_fsout_nonref, 0, INTERP_3_2_MEM_LEN ); +#endif + + hStereoICBWE->syn_dm_phase_nonref = 0; + + set32_fx( hStereoICBWE->memShbHilbert_nonref_fx, 0, HILBERT_MEM_SIZE ); + set32_fx( hStereoICBWE->memShbInterp_nonref_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set32_fx( hStereoICBWE->memShb_fsout_nonref_fx, 0, INTERP_3_2_MEM_LEN ); + + return; +} +#endif /*-------------------------------------------------------------------* * stereo_icBWE_dec() @@ -189,13 +237,22 @@ void stereo_icBWE_dec( /* core switching reset */ if ( st->last_core != ACELP_CORE || st->bwidth == WB ) { +#ifdef IVAS_FLOAT_FIXED + ic_bwe_dec_reset_fx( hStereoICBWE ); +#else ic_bwe_dec_reset( hStereoICBWE ); +#endif if ( st->last_core != ACELP_CORE ) { hStereoICBWE->prevSpecMapping = 0.0f; hStereoICBWE->prevgsMapping = 1.0f; hStereoICBWE->icbweM2Ref_prev = 1.0f; + +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->prevgsMapping_fx = ONE_IN_Q30; +#endif } if ( st->bwidth == WB ) @@ -208,13 +265,23 @@ void stereo_icBWE_dec( hStereoICBWE->prevSpecMapping = 0.0f; hStereoICBWE->prevgsMapping = 1.0f; hStereoICBWE->icbweM2Ref_prev = 1.0f; + +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->prevgsMapping_fx = ONE_IN_Q30; +#endif } else if ( st->element_mode == IVAS_CPE_DFT ) { hStereoICBWE->refChanIndx_bwe = L_CH_INDX; hStereoICBWE->prevSpecMapping = 0.0f; - prevgsMapping = hStereoICBWE->prevgsMapping; + +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->prevgsMapping_fx = float_to_fix( hStereoICBWE->prevgsMapping, Q30 ); +#endif + temp1 = hStereoDft->side_gain[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1]; icbweM2Ref = 1.f + temp1; gsMapping = 1.f - temp1; @@ -235,6 +302,10 @@ void stereo_icBWE_dec( } hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; hStereoICBWE->prevgsMapping = gsMapping; + +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevgsMapping_fx = float_to_fix( hStereoICBWE->prevgsMapping, Q30 ); +#endif } return; @@ -291,6 +362,11 @@ void stereo_icBWE_dec( hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevSpecMapping_fx = float_to_fix( hStereoICBWE->prevSpecMapping, Q31 ); + hStereoICBWE->prevgsMapping_fx = float_to_fix( hStereoICBWE->prevgsMapping, Q30 ); +#endif + specMapping = hStereoICBWE->prevSpecMapping; gsMapping = hStereoICBWE->prevgsMapping; @@ -336,6 +412,11 @@ void stereo_icBWE_dec( mvr2r( hStereoICBWE->mem_syn_shb_nonref, shb_synth_nonref, L_SHB_LAHEAD ); syn_filt( hStereoICBWE->lpSHBRef, LPC_SHB_ORDER, excSHB_nonref, shb_synth_nonref + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref, 1 ); +#ifdef IVAS_FLOAT_FIXED + Word16 q_mem_lpc_shbsynth_nonref = Q_factor_arr( hStereoICBWE->mem_lpc_shbsynth_nonref, LPC_SHB_ORDER ); + floatToFixed_arrL( hStereoICBWE->mem_lpc_shbsynth_nonref, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, q_mem_lpc_shbsynth_nonref, LPC_SHB_ORDER ); +#endif + prev_pow = sum2_f( shb_synth_nonref, L_SHB_LAHEAD + 10 ); curr_pow = sum2_f( shb_synth_nonref + L_SHB_LAHEAD + 10, L_SHB_LAHEAD + 10 ); @@ -363,8 +444,22 @@ void stereo_icBWE_dec( deemph( shb_synth_nonref + L_SHB_LAHEAD, specMapping, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping ) ); mvr2r( shb_synth_nonref + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref, L_SHB_LAHEAD ); + // dbgwrite_txt(&(hStereoICBWE->memShbSpecMapping), 1, "shbspecmap.txt", NULL); + +#ifdef IVAS_FLOAT_FIXED + Word16 q_mem_syn_shb_nonref = Q_factor_arr( hStereoICBWE->mem_syn_shb_nonref, L_SHB_LAHEAD ); + floatToFixed_arrL( hStereoICBWE->mem_syn_shb_nonref, hStereoICBWE->mem_syn_shb_nonref_fx, q_mem_syn_shb_nonref, L_SHB_LAHEAD ); // Q10 + hStereoICBWE->memShbSpecMapping_fx = float_to_fix( hStereoICBWE->memShbSpecMapping, Q20 ); // need to check this again +#endif + + ScaleShapedSHB( SHB_OVERLAP_LEN, shb_synth_nonref, hStereoICBWE->mem_syn_shb_ola_nonref, hStereoICBWE->gshapeRef, ( hStereoICBWE->gFrameRef * gsMapping * 0.9f ), window_shb, subwin_shb ); +#ifdef IVAS_FLOAT_FIXED + Word16 q_mem_syn_shb_ola_nonref = Q_factor_arr( hStereoICBWE->mem_syn_shb_ola_nonref, L_SHB_LAHEAD ); + floatToFixed_arrL( hStereoICBWE->mem_syn_shb_ola_nonref, hStereoICBWE->mem_syn_shb_ola_nonref_fx, q_mem_syn_shb_ola_nonref, L_SHB_LAHEAD ); +#endif + if ( st->extl == FB_TBE ) { v_multc( fb_synth_ref, gsMapping, fb_synth_nonref, L_FRAME48k ); @@ -372,6 +467,14 @@ void stereo_icBWE_dec( /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ GenSHBSynth( shb_synth_nonref, error, hStereoICBWE->memShbHilbert_nonref, hStereoICBWE->memShbInterp_nonref, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); + +#ifdef IVAS_FLOAT_FIXED + Word16 q_memShbInterp_nonref = Q_factor_arr( hStereoICBWE->memShbInterp_nonref, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + Word16 q_memShbHilbert_nonref = Q_factor_arr( hStereoICBWE->memShbHilbert_nonref, HILBERT_MEM_SIZE ); + + floatToFixed_arrL( hStereoICBWE->memShbHilbert_nonref, hStereoICBWE->memShbHilbert_nonref_fx, q_memShbHilbert_nonref, HILBERT_MEM_SIZE ); + floatToFixed_arrL( hStereoICBWE->memShbInterp_nonref, hStereoICBWE->memShbInterp_nonref_fx, q_memShbInterp_nonref, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); +#endif } else { @@ -414,9 +517,17 @@ void stereo_icBWE_dec( } hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; +#ifdef IVAS_FLOAT_FIXED + ic_bwe_dec_reset_fx( hStereoICBWE ); +#else ic_bwe_dec_reset( hStereoICBWE ); +#endif hStereoICBWE->prevSpecMapping = 0.0f; +#ifdef IVAS_FLOAT_FIXED + hStereoICBWE->prevSpecMapping_fx = 0; +#endif + return; } @@ -434,6 +545,10 @@ void stereo_icBWE_dec( Decimate_allpass_steep( error, hStereoICBWE->memShb_fsout_nonref, L_FRAME32k, synth ); } +#ifdef IVAS_FLOAT_FIXED + Word16 q_memShb_fsout_nonref = Q_factor_arr( hStereoICBWE->memShb_fsout_nonref, INTERP_3_2_MEM_LEN ); + floatToFixed_arrL( hStereoICBWE->memShb_fsout_nonref, hStereoICBWE->memShb_fsout_nonref_fx, q_memShb_fsout_nonref, INTERP_3_2_MEM_LEN ); +#endif if ( st->extl == FB_TBE && st->output_Fs == 48000 ) { @@ -511,7 +626,11 @@ void stereo_icBWE_decproc( if ( ( hCPE->element_mode == IVAS_CPE_TD || hCPE->element_mode == IVAS_CPE_DFT ) && hCPE->nchan_out == 2 /*&& hCPE->hCoreCoder[0]->core_brate > SID_2k40*/ && hCPE->hCoreCoder[0]->last_core_brate <= SID_2k40 ) { +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); +#else stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#endif } if ( hCPE->hCoreCoder[0]->core_brate <= SID_2k40 ) @@ -721,7 +840,11 @@ void stereo_icBWE_decproc( } else if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag && hStereoICBWE != NULL ) { - stereo_icBWE_init_dec( hStereoICBWE ); +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); +#else + stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#endif } else if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->last_element_mode == IVAS_CPE_DFT && last_core == ACELP_CORE ) { @@ -766,6 +889,355 @@ void stereo_icBWE_decproc( return; } +#ifdef IVAS_FLOAT_FIXED +void stereo_icBWE_decproc_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *output[CPE_CHANNELS], /* i/o: output synthesis */ + Word32 outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ + const int16_t last_core, /* i : last core, primary channel */ + const int16_t last_bwidth, /* i : last bandwidth */ + const int16_t output_frame /* i : frame length */ +) +{ + int16_t i, j, n, decoderDelay, icbweOLASize, dftOvlLen; + int16_t core, memOffset, refChanIndx_bwe; + + Word32 temp0_fx[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )], temp1_fx[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; + Word32 winSlope_fx = 0, alpha_fx; + const Word32 *win_dft_fx; + int32_t extl_brate, output_Fs; + + STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of SID or NO_DATA frame + * -------------------------------------------------------------------*/ + + IF( ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) || EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) && EQ_16( hCPE->nchan_out, 2 ) /*&& hCPE->hCoreCoder[0]->core_brate > SID_2k40*/ && LE_32( hCPE->hCoreCoder[0]->last_core_brate, SID_2k40 ) ) + { +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); +#else + stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#endif + } + + IF( LE_32( hCPE->hCoreCoder[0]->core_brate, SID_2k40 ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of mono DMX output * + * -------------------------------------------------------------------*/ + + IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + add_HB_to_mono_dmx_fx( hCPE, output[0], outputHB[0], last_core, output_frame ); + return; + } + ELSE IF( EQ_16( hCPE->nchan_out, 1 ) && NE_16( hCPE->element_mode, IVAS_CPE_TD ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * IC-BWE processing + * -------------------------------------------------------------------*/ + + core = hCPE->hCoreCoder[0]->core; + extl_brate = hCPE->hCoreCoder[0]->extl_brate; + output_Fs = hCPE->hCoreCoder[0]->output_Fs; + + memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); + + /* LRTD stereo mode - 2xBWEs used */ + IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) + { + /* delay HB synth */ + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + Copy32( outputHB[n] + output_frame - memOffset, temp0_fx, memOffset ); + Copy32( outputHB[n], outputHB[n] + memOffset, output_frame - memOffset ); + Copy32( hCPE->prev_hb_synth_fx[n], outputHB[n], memOffset ); + Copy32( temp0_fx, hCPE->prev_hb_synth_fx[n], memOffset ); + } + + IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + /* stereo to mono downmix */ + FOR( i = 0; i < output_frame; i++ ) + { + outputHB[0][i] = L_shr( ( outputHB[0][i] + outputHB[1][i] ), 1 ); + } + v_add_32( output[0], outputHB[0], output[0], output_frame ); + } + ELSE + { + /* Add the delayed hb_synth component to the delayed ACELP synthesis */ + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + v_add_32( output[n], outputHB[n], output[n], output_frame ); + } + } + } + ELSE + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + set32_fx( hCPE->prev_hb_synth_fx[n], 0, memOffset ); + } + } + + IF( NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) && !( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) + { + IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) + { + set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); + set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); + + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + + IF( EQ_16( core, ACELP_CORE ) && GT_32( extl_brate, 0 ) ) + { + refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && GT_16( hCPE->hCoreCoder[0]->bwidth, WB ) && EQ_16( last_bwidth, WB ) && GT_16( hCPE->hCoreCoder[0]->ini_frame, 1 ) /* counter wass already updated */ ) + { + /* fad-in reference HB signal */ + IF( GT_16( memOffset, 0 ) ) + { + switch ( memOffset ) + { + case 15: + winSlope_fx = 71582792; + break; + case 30: + winSlope_fx = 35791396; + break; + case 45: + winSlope_fx = 23860930; + break; + } + // memOffset for 16K 32K 48K are 15 30 45 respectively.camera + } + ELSE + { + winSlope_fx = 0; + } + for ( i = 0; i < memOffset; i++ ) + { + Word32 mul_win = Mpy_32_16_1( winSlope_fx, ( i + 1 ) ); // Q30 + Q0 - 15 = Q15 + mul_win = L_shl( mul_win, 15 ); // Q30 + outputHB[refChanIndx_bwe][i] = L_shl( Mpy_32_32( outputHB[refChanIndx_bwe][i] /* Q11 + Q30 - 31 = Q10)*/, mul_win ), 1 ); // + } + } + /* Resampled LB and HB offset */ + Copy32( outputHB[refChanIndx_bwe], temp0_fx + memOffset, output_frame - memOffset ); + Copy32( outputHB[!refChanIndx_bwe], temp1_fx + memOffset, output_frame - memOffset ); + + decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); + + IF( NE_16( last_core, ACELP_CORE ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ + icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); + + FOR( i = 0; i < decoderDelay; i++ ) + { + temp0_fx[i] = 0; + temp1_fx[i] = 0; + } + + assert( icbweOLASize > 0 ); + SWITCH( icbweOLASize ) + { + case 60: + winSlope_fx = 17895698; + break; + case 40: + winSlope_fx = 26843546; + break; + case 20: + winSlope_fx = 53687092; + break; + } + alpha_fx = winSlope_fx; // Q30 + FOR( ; i < decoderDelay + icbweOLASize; i++ ) + { + temp0_fx[i] = L_shl_sat( Mpy_32_32( temp0_fx[i], alpha_fx ), 1 ); // Q11 + temp1_fx[i] = L_shl_sat( Mpy_32_32( temp1_fx[i], alpha_fx ), 1 ); + alpha_fx = L_add( alpha_fx, winSlope_fx ); + } + } + ELSE + { + IF( NE_16( refChanIndx_bwe, hStereoICBWE->prev_refChanIndx_bwe ) ) + { + IF( GT_16( memOffset, 0 ) ) + { + SWITCH( memOffset ) + { + case 15: + winSlope_fx = 71582792; + break; + case 30: + winSlope_fx = 35791396; + break; + case 45: + winSlope_fx = 23860930; // Q30 + break; + } + // memOffset for 16K 32K 48K are 15 30 45 respectively.camera + } + ELSE + { + winSlope_fx = 0; + } + FOR( i = 0; i < memOffset; i++ ) + { + temp0_fx[i] = L_add( L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( i + 1 ) ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i] ), 16 ), + L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, 1 - ( i + 1 ) ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i] ), 16 ) ); + + temp1_fx[i] = L_add( L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( i + 1 ) ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i] ), 16 ), + L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( 1 - ( i + 1 ) ) ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i] ), 16 ) ); + } + } + ELSE + { + Copy32( hStereoICBWE->memOutHB_fx[refChanIndx_bwe], temp0_fx, memOffset ); + Copy32( hStereoICBWE->memOutHB_fx[!refChanIndx_bwe], temp1_fx, memOffset ); + } + } + + IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + /* stereo to mono downmix */ + FOR( i = 0; i < output_frame; i++ ) + { + temp0_fx[i] = L_add( temp0_fx[i], temp1_fx[i] ); + temp0_fx[i] = L_shr( temp0_fx[i], 1 ); + output[0][i] = L_add( output[0][i], temp0_fx[i] ); + } + } + ELSE + { + v_add_32( temp0_fx, output[0], output[0], output_frame ); + v_add_32( temp1_fx, output[1], output[1], output_frame ); + } + + Copy32( outputHB[0] + output_frame - memOffset, hStereoICBWE->memOutHB_fx[0], memOffset ); + Copy32( outputHB[1] + output_frame - memOffset, hStereoICBWE->memOutHB_fx[1], memOffset ); + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + /*win_dft = hCPE->hStereoDft->win32ms;*/ + win_dft_fx = (Word32 *) hCPE->hStereoDft->win32ms_fx; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + + /* Preparing buffers in anticipation of an ACELP to TCX switch */ + j = 0; + FOR( i = 0; i < memOffset; i++ ) + { + Word16 tmp_mul = mult0( STEREO_DFT32MS_STEP, ( dftOvlLen - 1 - j ) ); + hStereoICBWE->memTransitionHB_fx[0][i] = Mpy_32_32( hStereoICBWE->memOutHB_fx[0][i], win_dft_fx[tmp_mul] ); + hStereoICBWE->memTransitionHB_fx[1][i] = Mpy_32_32( hStereoICBWE->memOutHB_fx[1][i], win_dft_fx[tmp_mul] ); + j++; + } + + FOR( i = 0; j < dftOvlLen; i++ ) + { + Word16 tmp_mul = mult0( STEREO_DFT32MS_STEP, ( dftOvlLen - 1 - j ) ); + hStereoICBWE->memTransitionHB_fx[0][memOffset + i] = Mpy_32_32( outputHB[0][output_frame - i - 1], win_dft_fx[tmp_mul] ); + hStereoICBWE->memTransitionHB_fx[1][memOffset + i] = Mpy_32_32( outputHB[1][output_frame - i - 1], win_dft_fx[tmp_mul] ); + j++; + } + } + + hStereoICBWE->prev_refChanIndx_bwe = refChanIndx_bwe; + } + ELSE + { + IF( EQ_16( last_core, ACELP_CORE ) ) + { + IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) + { + v_add_32( output[0], hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], memOffset ); + v_add_32( output[1], hStereoICBWE->memOutHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], memOffset ); + } + ELSE + { + /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ + v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + + set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); + set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); + + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + } + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag && hStereoICBWE != NULL ) + { +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); +#else + stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#endif + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( last_core, ACELP_CORE ) ) + { + int16_t delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + + FOR( n = 0; n < hCPE->nchan_out; n++ ) + { + FOR( i = 0; i < delay_tdbwe; i++ ) + { + output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); + } + } + /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ + td_bwe_dec_init_fx( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_TD, +#ifdef ADD_IVAS_BWE + st_fx->extl, +#endif + output_Fs ); + fd_bwe_dec_init( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_FD ); + } + + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && ( max( hCPE->hStereoDft->td_gain_fx[0], hCPE->hStereoDft->td_gain_fx[1] ) > 0 ) ) + { + Word32 win_in_fx, win_out_fx, tmp_fx; + + win_dft_fx = (Word32 *) hCPE->hStereoDft->win32ms_fx; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + + FOR( i = 0; i < dftOvlLen; i++ ) + { + win_in_fx = Mpy_32_32( win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )], win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )] ); + win_out_fx = L_sub( 1, win_in_fx ); + tmp_fx = Mpy_32_32( L_add( Mpy_32_32( win_in_fx, hCPE->hStereoDft->td_gain_fx[0] ), Mpy_32_32( win_out_fx, hCPE->hStereoDft->td_gain_fx[1] ) ), hCPE->hStereoDft->hb_stefi_sig_fx[i] ); + output[0][i] = L_add( output[0][i], tmp_fx ); + output[1][i] = L_sub( output[1][i], tmp_fx ); + } + FOR( i = dftOvlLen; i < output_frame; i++ ) + { + tmp_fx = Mpy_32_32( hCPE->hStereoDft->td_gain_fx[0], hCPE->hStereoDft->hb_stefi_sig_fx[i] ); + output[0][i] = L_add_sat( output[0][i], tmp_fx ); + output[1][i] = L_sub_sat( output[1][i], tmp_fx ); + } + } + + return; +} +#endif + /*-------------------------------------------------------------------* * stereo_icBWE_init_dec() * @@ -798,7 +1270,58 @@ void stereo_icBWE_init_dec( hStereoICBWE->prev_spIndx = 0; hStereoICBWE->prev_gsIndx = 0; +#ifdef IVAS_FLOAT_FIXED + ic_bwe_dec_reset_fx( hStereoICBWE ); +#else ic_bwe_dec_reset( hStereoICBWE ); +#endif + + return; +} + +#ifdef IVAS_FLOAT_FIXED +void stereo_icBWE_init_dec_fx( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ +) +{ + /* BWE ref channel */ + hStereoICBWE->refChanIndx_bwe = L_CH_INDX; + hStereoICBWE->prev_refChanIndx_bwe = L_CH_INDX; + + /* SHB output memory */ +#if 1 /* TODO: remove float init later. */ + set_f( hStereoICBWE->memOutHB[0], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + set_f( hStereoICBWE->memOutHB[1], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); +#endif + + set32_fx( hStereoICBWE->memOutHB_fx[0], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + set32_fx( hStereoICBWE->memOutHB_fx[1], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + + /* SHB output memory */ +#if 1 /*TODO: remove float init later. */ + set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); +#endif + + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + + /* inter-channel BWE spectral shape adj. */ +#if 1 /* TODO: remove float init later*/ + hStereoICBWE->prevSpecMapping = 0; + hStereoICBWE->prevgsMapping = 1.0f; + hStereoICBWE->icbweM2Ref_prev = 1.0f; +#endif + + hStereoICBWE->prevSpecMapping_fx = 0; + hStereoICBWE->prevgsMapping_fx = ONE_IN_Q30; + hStereoICBWE->icbweM2Ref_prev_fx = ONE_IN_Q30; + + hStereoICBWE->prev_spIndx = 0; + hStereoICBWE->prev_gsIndx = 0; + + ic_bwe_dec_reset_fx( hStereoICBWE ); return; } +#endif \ No newline at end of file diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 615a9cb2ea84466b49f721dd1a514bc1edf3fb7c..7ddc07758834558c473cdeb30f28e1e677974f98 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -41,6 +41,8 @@ #include "assert.h" #include "wmc_auto.h" #include +#include "prot_fx2.h" +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * Local constants @@ -447,7 +449,11 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE \n" ) ); } - stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx(hCPE->hStereoICBWE); +#else + stereo_icBWE_init_dec(hCPE->hStereoICBWE); +#endif } /* allocate HQ core */ @@ -558,7 +564,11 @@ ivas_error stereo_memory_dec( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo DFT mono output\n" ) ); } - stereo_dft_dmx_out_reset( hCPE->hStereoDftDmx ); +#ifdef IVAS_FLOAT_FIXED + stereo_dft_dmx_out_reset_fx(hCPE->hStereoDftDmx); +#else + stereo_dft_dmx_out_reset(hCPE->hStereoDftDmx); +#endif } /* allocate TCA data structure */ @@ -568,8 +578,11 @@ ivas_error stereo_memory_dec( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo TCA\n" ) ); } - +#ifdef IVAS_FLOAT_FIXED + stereo_tca_init_dec_fx( hCPE->hStereoTCA ); +#else stereo_tca_init_dec( hCPE->hStereoTCA ); +#endif } st = hCPE->hCoreCoder[0]; @@ -830,7 +843,11 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE \n" ) ); } - stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx(hCPE->hStereoICBWE); +#else + stereo_icBWE_init_dec(hCPE->hStereoICBWE); +#endif } } } @@ -854,7 +871,11 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo TCA\n" ) ); } } +#ifdef IVAS_FLOAT_FIXED + stereo_tca_init_dec_fx( hCPE->hStereoTCA ); +#else stereo_tca_init_dec( hCPE->hStereoTCA ); +#endif } hCPE->hStereoMdct->use_itd = 1; @@ -893,7 +914,11 @@ ivas_error stereo_memory_dec( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo DFT mono output\n" ) ); } - stereo_dft_dmx_out_reset( hCPE->hStereoDftDmx ); +#ifdef IVAS_FLOAT_FIXED + stereo_dft_dmx_out_reset_fx(hCPE->hStereoDftDmx); +#else + stereo_dft_dmx_out_reset(hCPE->hStereoDftDmx); +#endif } if ( hCPE->prev_synth_chs[1] != NULL ) @@ -933,7 +958,11 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE \n" ) ); } - stereo_icBWE_init_dec( hCPE->hStereoICBWE ); +#ifdef IVAS_FLOAT_FIXED + stereo_icBWE_init_dec_fx(hCPE->hStereoICBWE); +#else + stereo_icBWE_init_dec(hCPE->hStereoICBWE); +#endif } if ( hCPE->hStereoTCA == NULL && ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_TD ) ) @@ -943,7 +972,11 @@ ivas_error stereo_memory_dec( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo TCA\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + stereo_tca_init_dec_fx( hCPE->hStereoTCA ); +#else stereo_tca_init_dec( hCPE->hStereoTCA ); +#endif } if ( hCPE->element_mode == IVAS_CPE_MDCT ) @@ -1746,7 +1779,7 @@ void stereo_td2dft_update( mvr2r( output + sts[n]->L_frame - ovl, hCPE->input_mem_LB[n], ovl ); /* update DFT analysis overlap memory @internal_fs: BPF */ - if ( sts[n]->p_bpf_noise_buf_float) + if ( sts[n]->p_bpf_noise_buf_float ) { mvr2r( sts[n]->p_bpf_noise_buf_float + sts[n]->L_frame - ovl, hCPE->input_mem_BPF[n], ovl ); } @@ -1769,7 +1802,7 @@ void stereo_td2dft_update( mvr2r( output + sts[n]->L_frame - ovl, hCPE->input_mem_LB[n], ovl ); /* BPF */ - if ( n == 0 && sts[n]->p_bpf_noise_buf_float) + if ( n == 0 && sts[n]->p_bpf_noise_buf_float ) { mvr2r( sts[n]->p_bpf_noise_buf_float + sts[n]->L_frame - ovl, hCPE->input_mem_BPF[n], ovl ); }