diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index d7b41adbe9f4e314f0f9c91f6270b3b439fde21f..fc5d9eb97eabb76a7a2cfe050e5d3dc17573c5f0 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4384,6 +4384,21 @@ Word16 matrix_product_fx( Word32 *Z_fx /* o : resulting matrix after the matrix multiplication */ ); +Word16 matrix_product_mant_exp( + const Word32 *X_fx, /* i : left hand matrix */ + const Word16 *X_e, /* i : left hand matrix */ + const Word16 rowsX, /* i : number of rows of the left hand matrix */ + const Word16 colsX, /* i : number of columns of the left hand matrix */ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication */ + const Word32 *Y_fx, /* i : right hand matrix */ + const Word16 *Y_e, /* i : right hand matrix */ + const Word16 rowsY, /* i : number of rows of the right hand matrix */ + const Word16 colsY, /* i : number of columns of the right hand matrix */ + const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ + Word32 *Z_fx, /* o : resulting matrix after the matrix multiplication */ + Word16 *Z_e /* o : resulting matrix after the matrix multiplication */ +); + void mat2svdMat_fx( const Word32 *mat, /* i : matrix as column ordered vector */ Word32 svdMat[MAX_OUTPUT_CHANNELS][MAX_OUTPUT_CHANNELS], /* o : matrix as two-dimensional arry */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 2189501baad1f8c102ad65000aa28b64e477bae8..2afc0ed2bac173fbac6db975f42589d054ee9a2a 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1509,4 +1509,19 @@ void synchro_synthesis_fixed_clean( const Word16 output_frame, /* i : Number of samples */ const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ); + +//ivas_dirac_output_synthesis_cov +void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( + Word32 *RealBuffer_fx, /* i : input channel filter bank samples (real part) */ + Word16 RealBuffer_e, /* i : exponent input channel filter bank samples (real part)*/ + Word32 *ImagBuffer_fx, /* i : input channel filter bank samples (imaginary part */ + Word16 ImagBuffer_e, /* i : exponent input channel filter bank samples (real part)*/ + Word32 cx_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (real part) */ + Word16 *cx_e, /* i : exponent for accumulated input covariance (real part) */ + Word32 cx_imag_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (imaginary part) */ + Word16 *cx_imag_e, /* i : exponent accumulated input covariance (imag part) */ + PARAM_MC_DEC_HANDLE hParamMC, /* i : handle to Parametric MC state */ + const Word16 nchan_in /* i : number of input channels */ +); + #endif diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 3cf9e08f1f2e4e87356973bbf75dae8282180e02..86fa9f4163f6ad54602c1606f97bc0a4a69f68ac 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -2041,6 +2041,16 @@ const float ivas_param_mc_ild_fac_CICP6_2tc[6] = 0.323713613305539f, 0.208150823035836f, }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP6_2tc_fx[6] = +{ + 12832, + 12832, + 6820, + 10607, + 10607, + 6820 +}; const float ivas_param_mc_ild_fac_CICP12_2tc[8] = { @@ -2053,6 +2063,18 @@ const float ivas_param_mc_ild_fac_CICP12_2tc[8] = 0.171473949468979f, 0.208008958987949f }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP12_2tc_fx[8] = +{ + 11965, + 11965, + 6816, + 6877, + 6877, + 5619, + 5619, + 6816 +}; const float ivas_param_mc_ild_fac_CICP12_3tc[8] = { @@ -2065,6 +2087,18 @@ const float ivas_param_mc_ild_fac_CICP12_3tc[8] = 1.0f, 0.25f }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP12_3tc_fx[8] = +{ + 16384, + 16384, + 9502, + 9502, + 6553, + 6553, + 32767, + 8192 +}; const float ivas_param_mc_ild_fac_CICP14_2tc[8] = { @@ -2077,6 +2111,18 @@ const float ivas_param_mc_ild_fac_CICP14_2tc[8] = 0.24564756f, 0.20800895f }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP14_2tc_fx[8] = +{ + 11936, + 11936, + 5993, + 6945, + 6945, + 8049, + 8049, + 6816 +}; const float ivas_param_mc_ild_fac_CICP14_3tc[8] = { @@ -2089,6 +2135,18 @@ const float ivas_param_mc_ild_fac_CICP14_3tc[8] = 1.0f, 0.25f }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP14_3tc_fx[8] = +{ + 16291, + 16291, + 8257, + 8257, + 9666, + 9666, + 32767, + 8192 +}; const float ivas_param_mc_ild_fac_CICP16_3tc[10] = { @@ -2103,6 +2161,20 @@ const float ivas_param_mc_ild_fac_CICP16_3tc[10] = 1.0f, 0.25f, }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP16_3tc_fx[10] = +{ + 11141, + 11141, + 7209, + 7209, + 6553, + 6553, + 5898, + 5898, + 32767, + 8192 +}; const float ivas_param_mc_ild_fac_CICP19_3tc[12] = { @@ -2119,6 +2191,22 @@ const float ivas_param_mc_ild_fac_CICP19_3tc[12] = 1.0f, 0.5f }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP19_3tc_fx[12] = +{ + 9830, + 9830, + 5570, + 5570, + 3932, + 3932, + 6226, + 6226, + 6226, + 6226, + 32767, + 16384 +}; const float ivas_param_mc_ild_fac_CICP19_4tc[12] = { @@ -2135,6 +2223,22 @@ const float ivas_param_mc_ild_fac_CICP19_4tc[12] = 0.5f, 0.2f, }; +//Q15 +const Word16 ivas_param_mc_ild_fac_CICP19_4tc_fx[12] = +{ + 11468, + 11468, + 5570, + 7209, + 6553, + 6553, + 6553, + 16384, + 16384, + 16384, + 16384, + 6553 +}; const PARAM_MC_ILD_MAPPING ivas_param_mc_ild_mapping_CICP6_2tc = { @@ -2335,7 +2439,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP6_2tc, &ivas_param_mc_icc_mapping_CICP6_2tc, &ivas_param_mc_dmx_fac_CICP6_2tc[0], - &ivas_param_mc_ild_fac_CICP6_2tc[0] + &ivas_param_mc_ild_fac_CICP6_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP6_2tc_fx[0] +#endif }, /* CICP6 64000 */ { @@ -2346,7 +2453,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP6_2tc, &ivas_param_mc_icc_mapping_CICP6_2tc, &ivas_param_mc_dmx_fac_CICP6_2tc[0], - &ivas_param_mc_ild_fac_CICP6_2tc[0] + &ivas_param_mc_ild_fac_CICP6_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP6_2tc_fx[0] +#endif }, /* CICP6 80000 */ { @@ -2357,7 +2467,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP6_2tc, &ivas_param_mc_icc_mapping_CICP6_2tc, &ivas_param_mc_dmx_fac_CICP6_2tc[0], - &ivas_param_mc_ild_fac_CICP6_2tc[0] + &ivas_param_mc_ild_fac_CICP6_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP6_2tc_fx[0] +#endif }, /* CICP12 48000 */ { @@ -2368,7 +2481,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP12_2tc, &ivas_param_mc_icc_mapping_CICP12_2tc, &ivas_param_mc_dmx_fac_CICP12_2tc[0], - &ivas_param_mc_ild_fac_CICP12_2tc[0] + &ivas_param_mc_ild_fac_CICP12_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP12_2tc_fx[0] +#endif }, /* CICP12 64000 */ { @@ -2379,7 +2495,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP12_2tc, &ivas_param_mc_icc_mapping_CICP12_2tc, &ivas_param_mc_dmx_fac_CICP12_2tc[0], - &ivas_param_mc_ild_fac_CICP12_2tc[0] + &ivas_param_mc_ild_fac_CICP12_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP12_2tc_fx[0] +#endif }, /* CICP12 80000 */ { @@ -2390,7 +2509,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP12_2tc, &ivas_param_mc_icc_mapping_CICP12_2tc, &ivas_param_mc_dmx_fac_CICP12_2tc[0], - &ivas_param_mc_ild_fac_CICP12_2tc[0] + &ivas_param_mc_ild_fac_CICP12_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP12_2tc_fx[0] +#endif }, /* CICP12 96000 */ { @@ -2401,7 +2523,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP12_3tc, &ivas_param_mc_icc_mapping_CICP12_3tc, &ivas_param_mc_dmx_fac_CICP12_3tc[0], - &ivas_param_mc_ild_fac_CICP12_3tc[0] + &ivas_param_mc_ild_fac_CICP12_3tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP12_3tc_fx[0] +#endif }, /* CICP14 48000 */ { @@ -2412,7 +2537,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP14_2tc, &ivas_param_mc_icc_mapping_CICP14_2tc, &ivas_param_mc_dmx_fac_CICP14_2tc[0], - &ivas_param_mc_ild_fac_CICP14_2tc[0] + &ivas_param_mc_ild_fac_CICP14_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP14_2tc_fx[0] +#endif }, /* CICP14 64000 */ { @@ -2423,7 +2551,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP14_2tc, &ivas_param_mc_icc_mapping_CICP14_2tc, &ivas_param_mc_dmx_fac_CICP14_2tc[0], - &ivas_param_mc_ild_fac_CICP14_2tc[0] + &ivas_param_mc_ild_fac_CICP14_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP14_2tc_fx[0] +#endif }, /* CICP14 80000 */ { @@ -2434,7 +2565,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP14_2tc, &ivas_param_mc_icc_mapping_CICP14_2tc, &ivas_param_mc_dmx_fac_CICP14_2tc[0], - &ivas_param_mc_ild_fac_CICP14_2tc[0] + &ivas_param_mc_ild_fac_CICP14_2tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP14_2tc_fx[0] +#endif }, /* CICP14 96000 */ { @@ -2445,7 +2579,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP14_3tc, &ivas_param_mc_icc_mapping_CICP14_3tc, &ivas_param_mc_dmx_fac_CICP14_3tc[0], - &ivas_param_mc_ild_fac_CICP14_3tc[0] + &ivas_param_mc_ild_fac_CICP14_3tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP14_3tc_fx[0] +#endif }, /* CICP16 96000 */ { @@ -2456,8 +2593,11 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP16_3tc, &ivas_param_mc_icc_mapping_CICP16_3tc, &ivas_param_mc_dmx_fac_CICP16_3tc[0], - &ivas_param_mc_ild_fac_CICP16_3tc[0] - }, + &ivas_param_mc_ild_fac_CICP16_3tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP16_3tc_fx[0] +#endif + }, /* CICP16 128000 */ { MC_LS_SETUP_5_1_4, @@ -2467,8 +2607,11 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP16_3tc, &ivas_param_mc_icc_mapping_CICP16_3tc, &ivas_param_mc_dmx_fac_CICP16_3tc[0], - &ivas_param_mc_ild_fac_CICP16_3tc[0] - }, + &ivas_param_mc_ild_fac_CICP16_3tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP16_3tc_fx[0] +#endif + }, /* CICP19 128000 */ { MC_LS_SETUP_7_1_4, @@ -2478,7 +2621,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP19_3tc, &ivas_param_mc_icc_mapping_CICP19_3tc, &ivas_param_mc_dmx_fac_CICP19_3tc[0], - &ivas_param_mc_ild_fac_CICP19_3tc[0] + &ivas_param_mc_ild_fac_CICP19_3tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP19_3tc_fx[0] +#endif }, /* CICP19 160000 */ { @@ -2489,7 +2635,10 @@ const PARAM_MC_CONF ivas_param_mc_conf[PARAM_MC_NUM_CONFIGS] = &ivas_param_mc_ild_mapping_CICP19_4tc, &ivas_param_mc_icc_mapping_CICP19_4tc, &ivas_param_mc_dmx_fac_CICP19_4tc[0], - &ivas_param_mc_ild_fac_CICP19_4tc[0] + &ivas_param_mc_ild_fac_CICP19_4tc[0], +#ifdef IVAS_FLOAT_FIXED + &ivas_param_mc_ild_fac_CICP19_4tc_fx[0] +#endif } }; diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 6985cbc4ea56ccb90010ca37a90d17899aed1f40..c9d4aa5875badd8e873b68392c56b9cb2cdfff8d 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1257,6 +1257,156 @@ Word16 matrix_product_fx( return EXIT_SUCCESS; } + +/*takes input matrices in mantissa and exponent forms*/ +Word16 matrix_product_mant_exp( + const Word32 *X_fx, /* i : left hand matrix */ + const Word16 *X_e, /* i : left hand matrix */ + const Word16 rowsX, /* i : number of rows of the left hand matrix */ + const Word16 colsX, /* i : number of columns of the left hand matrix */ + const Word16 transpX, /* i : flag indicating the transposition of the left hand matrix prior to the multiplication */ + const Word32 *Y_fx, /* i : right hand matrix */ + const Word16 *Y_e, /* i : right hand matrix */ + const Word16 rowsY, /* i : number of rows of the right hand matrix */ + const Word16 colsY, /* i : number of columns of the right hand matrix */ + const Word16 transpY, /* i : flag indicating the transposition of the right hand matrix prior to the multiplication */ + Word32 *Z_fx, /* o : resulting matrix after the matrix multiplication */ + Word16 *Z_e /* o : resulting matrix after the matrix multiplication */ +) +{ + Word16 i, j, k; + Word32 *Zp = Z_fx; + Word16 *Zp_e = Z_e; + Word32 L_tmp; + Word16 tmp_e; + + /* Processing */ + test(); + test(); + test(); + IF( EQ_16( transpX, 1 ) && EQ_16( transpY, 0 ) ) /* We use X transpose */ + { + IF( NE_16( rowsX, rowsY ) ) + { + return EXIT_FAILURE; + } + FOR( j = 0; j < colsY; ++j ) + { + FOR( i = 0; i < colsX; ++i ) + { + ( *Zp ) = 0; + move32(); + ( *Zp_e ) = 0; + move16(); + FOR( k = 0; k < rowsX; ++k ) + { + //( *Zp ) += X[k + i * rowsX] * Y[k + j * rowsY]; + L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[k + j * rowsY] ); + tmp_e = add( X_e[k + i * rowsX], Y_e[k + j * rowsY] ); + + ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); + ( *Zp_e ) = tmp_e; + move16(); + } + Zp++; + Zp_e++; + } + } + } + ELSE IF( EQ_16( transpX, 0 ) && EQ_16( transpY, 1 ) ) /* We use Y transpose */ + { + IF( NE_16( colsX, colsY ) ) + { + return EXIT_FAILURE; + } + FOR( j = 0; j < rowsY; ++j ) + { + FOR( i = 0; i < rowsX; ++i ) + { + ( *Zp ) = 0; + move32(); + ( *Zp_e ) = 0; + move16(); + FOR( k = 0; k < colsX; ++k ) + { + //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[j + k * rowsY]; + L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[j + k * rowsY] ); + tmp_e = add( X_e[i + k * rowsX], Y_e[j + k * rowsY] ); + + ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); + ( *Zp_e ) = tmp_e; + move16(); + } + Zp++; + Zp_e++; + } + } + } + ELSE IF( EQ_16( transpX, 1 ) && EQ_16( transpY, 1 ) ) /* We use both transpose */ + { + IF( NE_16( rowsX, colsY ) ) + { + return EXIT_FAILURE; + } + FOR( j = 0; j < rowsY; ++j ) + { + FOR( i = 0; i < colsX; ++i ) + { + ( *Zp ) = 0; + move32(); + ( *Zp_e ) = 0; + move16(); + FOR( k = 0; k < colsX; ++k ) + { + //( *Zp ) += X_fx[k + i * rowsX] * Y_fx[j + k * rowsY]; + L_tmp = Mpy_32_32( X_fx[k + i * rowsX], Y_fx[j + k * rowsY] ); + tmp_e = add( X_e[k + i * rowsX], Y_e[j + k * rowsY] ); + + ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); + ( *Zp_e ) = tmp_e; + move16(); + } + + Zp++; + Zp_e++; + } + } + } + ELSE /* Regular case */ + { + IF( NE_16( colsX, rowsY ) ) + { + return EXIT_FAILURE; + } + + FOR( j = 0; j < colsY; ++j ) + { + FOR( i = 0; i < rowsX; ++i ) + { + ( *Zp ) = 0; + move32(); + ( *Zp_e ) = 0; + move16(); + FOR( k = 0; k < colsX; ++k ) + { + //( *Zp ) += X_fx[i + k * rowsX] * Y_fx[k + j * rowsY]; + L_tmp = Mpy_32_32( X_fx[i + k * rowsX], Y_fx[k + j * rowsY] ); + tmp_e = add( X_e[i + k * rowsX], Y_e[k + j * rowsY] ); + + ( *Zp ) = BASOP_Util_Add_Mant32Exp( *Zp, *Zp_e, L_tmp, tmp_e, &tmp_e ); + ( *Zp_e ) = tmp_e; + move16(); + } + Zp++; + Zp_e++; + } + } + } + + return EXIT_SUCCESS; +} + + #endif /*---------------------------------------------------------------------* diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 9c53c320acd337181cc7fcf641a2b282e7d7f4f2..606997c5f08504a259e10dd0b19321a99fedaf30 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -5417,6 +5417,17 @@ void v_add_fixed( const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ ); +void v_add_fixed_me( + const Word32 x1[], /* i : Input vector 1 */ + const Word16 x1_e, /* i : Exponent for input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + const Word16 x2_e, /* i : Exponent for input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + Word16 *y_e, /* i : Exponent for output vector */ + const Word16 N, /* i : Vector length */ + const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ +); + void v_add_w64( const Word64 x1[], /* i : Input vector 1 */ const Word64 x2[], /* i : Input vector 2 */ diff --git a/lib_com/tools.c b/lib_com/tools.c index ed46d2cf1e89bd735623947c36c268b4d4d61d75..57e4afdb78a13f34e52c8560147aa3b35302b016 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -1076,6 +1076,32 @@ void v_add_fixed( return; } +void v_add_fixed_me( + const Word32 x1[], /* i : Input vector 1 */ + const Word16 x1_e, /* i : Exponent for input vector 1 */ + const Word32 x2[], /* i : Input vector 2 */ + const Word16 x2_e, /* i : Exponent for input vector 2 */ + Word32 y[], /* o : Output vector that contains vector 1 - vector 2 */ + Word16 *y_e, /* i : Exponent for output vector */ + const Word16 N, /* i : Vector length */ + const Word16 hdrm /* i : headroom for when subtraction result > 1 or < -1 */ +) +{ + Word16 i; + Word16 x1_shift = s_max(x1_e, x2_e) - x1_e; + Word16 x2_shift = s_max(x1_e, x2_e) - x2_e; + + FOR( i = 0; i < N; i++ ) + { + y[i] = L_add( L_shr( x1[i], hdrm + x1_shift ), L_shr( x2[i], hdrm + x2_shift ) ); + } + + *y_e = s_max(x1_e, x2_e) + hdrm; + + return; +} + + /*-------------------------------------------------------------------* * v_add_w64() * diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index 39e295f33683558e93a5dbb483f5178e3c4b329a..4dd43ef17dbd665511e5da4d57909bf05c0bb836 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -397,6 +397,140 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( return; } +#ifdef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot() + * + * collect the multi channel input covariance for one filter bank time slot + *-------------------------------------------------------------------*/ + +void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( + Word32 *RealBuffer_fx, /* i : input channel filter bank samples (real part) */ + Word16 RealBuffer_e, /* i : exponent input channel filter bank samples (real part)*/ + Word32 *ImagBuffer_fx, /* i : input channel filter bank samples (imaginary part */ + Word16 ImagBuffer_e, /* i : exponent input channel filter bank samples (real part)*/ + Word32 cx_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (real part) */ + Word16 *cx_e, /* i : exponent for accumulated input covariance (real part) */ + Word32 cx_imag_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (imaginary part) */ + Word16 *cx_imag_e, /* i : exponent accumulated input covariance (imag part) */ + PARAM_MC_DEC_HANDLE hParamMC, /* i : handle to Parametric MC state */ + const Word16 nchan_in /* i : number of input channels */ +) +{ + Word16 cx_init_e[PARAM_MC_MAX_PARAMETER_BANDS]; + Word16 cx_init_imag_e[PARAM_MC_MAX_PARAMETER_BANDS]; + Word16 param_band, band_idx, ch_idx; + Word16 brange[2]; + Word32 real_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * MAX_TRANSPORT_CHANNELS]; + Word16 real_in_e; + Word32 imag_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * MAX_TRANSPORT_CHANNELS]; + Word16 imag_in_e; + Word32 real_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 imag_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 output_e; + Word16 i, j, tmp1, tmp2, tmp1_e, tmp2_e, shift_imag, shift_real; + Word32 L_tmp; + Word16 band, num_bands; + + + // set16_fx(cx_tmp_e, 0, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS); + + /* estimate input covariance */ + FOR( param_band = 0; param_band < hParamMC->num_param_bands_synth; param_band++ ) + { + /* Already stack here instead of in the process_subframe */ + + /* collect input frame */ + brange[0] = hParamMC->band_grouping[param_band]; + move16(); + brange[1] = hParamMC->band_grouping[param_band + 1]; + move16(); + num_bands = brange[1] - brange[0]; + move16(); + + FOR( band_idx = 0; band_idx < num_bands; band_idx++ ) + { + band = brange[0] + band_idx; + move16(); + FOR( ch_idx = 0; ch_idx < nchan_in; ch_idx++ ) + { + real_in_buffer_fx[band_idx + num_bands * ch_idx] = RealBuffer_fx[ch_idx * hParamMC->num_freq_bands + band]; + move32(); + imag_in_buffer_fx[band_idx + num_bands * ch_idx] = ImagBuffer_fx[ch_idx * hParamMC->num_freq_bands + band]; + move32(); + } + } + + real_in_e = RealBuffer_e; + move16(); + imag_in_e = ImagBuffer_e; + move16(); + shift_real = sub( L_norm_arr( real_in_buffer_fx, num_bands * nchan_in ), find_guarded_bits_fx( num_bands + 1 ) ); + shift_imag = sub( L_norm_arr( imag_in_buffer_fx, num_bands * nchan_in ), find_guarded_bits_fx( num_bands + 1 ) ); + + real_in_e = sub( real_in_e, shift_real ); + imag_in_e = sub( imag_in_e, shift_imag ); + + + output_e = s_max( real_in_e, imag_in_e ); + + FOR( i = 0; i < num_bands * nchan_in; ++i ) + { + real_in_buffer_fx[i] = L_shr( real_in_buffer_fx[i], output_e - RealBuffer_e ); + move32(); + imag_in_buffer_fx[i] = L_shr( imag_in_buffer_fx[i], output_e - ImagBuffer_e ); + move32(); + } + + cmplx_matrix_square_fx( real_in_buffer_fx, imag_in_buffer_fx, num_bands, nchan_in, real_buffer_fx, imag_buffer_fx, output_e, &output_e ); + + v_add_fixed_me( cx_fx[param_band], *cx_e, real_buffer_fx, output_e, cx_fx[param_band], &tmp1_e, nchan_in * nchan_in, 1 ); + + v_add_fixed_me( cx_imag_fx[param_band], *cx_imag_e, imag_buffer_fx, output_e, cx_imag_fx[param_band], &tmp2_e, nchan_in * nchan_in, 1 ); + + cx_init_e[param_band] = tmp1_e; + move16(); + cx_init_imag_e[param_band] = tmp2_e; + move16(); + } + + // normalizing both the matrices to a common exponent for a better precision + tmp1 = 0; + move16(); + tmp2 = 0; + move16(); + FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ ) + { + FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) + { + L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[i][j], cx_init_e[i], 0, 0, &tmp1_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[i][j], cx_init_imag_e[i], 0, 0, &tmp2_e ); + tmp1 = s_max( tmp1, tmp1_e ); + tmp2 = s_max( tmp2, tmp2_e ); + } + } + + FOR( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ ) + { + FOR( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) + { + L_tmp = BASOP_Util_Add_Mant32Exp( cx_fx[i][j], cx_init_e[i], 0, 0, &tmp1_e ); + cx_fx[i][j] = L_shr( L_tmp, tmp1 - tmp1_e ); + move32(); + L_tmp = BASOP_Util_Add_Mant32Exp( cx_imag_fx[i][j], cx_init_imag_e[i], 0, 0, &tmp2_e ); + cx_imag_fx[i][j] = L_shr( L_tmp, tmp2 - tmp2_e ); + move32(); + } + } + + *cx_e = tmp1; + move16(); + *cx_imag_e = tmp2; + move16(); + + return; +} +#endif /*-------------------------------------------------------------------* * ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot() diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index e621f95db9acb52d248df1fda77741b86f41d3f8..11d3aaf77aa055c85399fa7d58f85666863e66c4 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -51,6 +51,8 @@ #include "ivas_prot_fx.h" #endif +#define INV_EPSILON_MANT 214748365 + /*-----------------------------------------------------------------------* * Local constants *-----------------------------------------------------------------------*/ @@ -101,6 +103,10 @@ static void ivas_param_mc_get_param_band_mapping( const int16_t n_target_bands, static void ivas_param_mc_bs_decode_parameter_values( uint16_t bit_buffer[], int16_t *bit_pos, const int16_t max_bits, int16_t *BER_detect, HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParamCodingInfo, const int16_t map_size_wo_lfe, const int16_t map_size, const int16_t num_lfe_bands, const int16_t band_step, const int16_t num_param_bands, float *value_buffer ); +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_mc_dequantize_cov_fx(PARAM_MC_DEC_HANDLE hParamMC, Word16 *ild_q_fx, Word16 *icc_q_fx, const Word16 param_band_index, const Word16 nY_cov, const PARAM_MC_SYNTHESIS_CONF synth_conf, const Word16 nY_int, const Word16 nX, Word32 *Cx_state_fx, Word16 Cx_state_e, Word32 *Cproto_fx, Word16 Cproto_e, Word32 *Cy_state_fx, Word16 *Cy_state_e); +#endif + /*------------------------------------------------------------------------- * ivas_param_mc_dec_open() * @@ -291,6 +297,12 @@ ivas_error ivas_param_mc_dec_open( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + IF ( ( hParamMC->ls_conv_dmx_matrix_fx = (Word32 *) malloc( nchan_out_transport * nchan_out_cov * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } +#endif for ( k = 0; k < nchan_out_transport; k++ ) { @@ -469,12 +481,28 @@ ivas_error ivas_param_mc_dec_open( } set_zero( hParamMC->Cldfb_RealBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + IF ( ( hParamMC->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set32_fx( hParamMC->Cldfb_RealBuffer_tc_fx, 0, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); +#endif + if ( ( hParamMC->Cldfb_ImagBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); } set_zero( hParamMC->Cldfb_ImagBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + IF ( ( hParamMC->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set32_fx( hParamMC->Cldfb_ImagBuffer_tc_fx, 0, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); +#endif + if ( st_ivas->hTcBuffer == NULL ) { #ifdef IVAS_FLOAT_FIXED @@ -1526,7 +1554,93 @@ void ivas_param_mc_dec_digest_tc( } if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) { +#ifdef IVAS_FLOAT_FIXED + Word32( *cx_fx )[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 cx_e; + Word32( *cx_imag_fx )[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 cx_imag_e; + Word16 cldfb_slots; + + cx_fx = malloc( sizeof( Word32[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS] ) ); + cx_imag_fx = malloc( sizeof( Word32[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS] ) ); + + for ( int lp = 0; lp < PARAM_MC_MAX_PARAMETER_BANDS; lp++ ) + { + set32_fx( cx_fx[lp], 0, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set32_fx( cx_imag_fx[lp], 0, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + } + + cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; + } + + f2me_buf( hParamMC->Cldfb_RealBuffer_tc, hParamMC->Cldfb_RealBuffer_tc_fx, &hParamMC->Cldfb_RealBuffer_tc_e, cldfb_slots * st_ivas->nchan_transport * hParamMC->num_freq_bands ); + f2me_buf( hParamMC->Cldfb_ImagBuffer_tc, hParamMC->Cldfb_ImagBuffer_tc_fx, &hParamMC->Cldfb_ImagBuffer_tc_e, cldfb_slots * st_ivas->nchan_transport * hParamMC->num_freq_bands ); + + Word16 max_e = 0; + cx_e; + for ( int lp = 0; lp < PARAM_MC_MAX_PARAMETER_BANDS; lp++ ) + { + for ( int lp2 = 0; lp2 < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; lp2++ ) + { + f2me( cx[lp][lp2], &cx_fx[lp][lp2], &cx_e ); + max_e = s_max( cx_e, max_e ); + } + } + + for ( int lp = 0; lp < PARAM_MC_MAX_PARAMETER_BANDS; lp++ ) + { + for ( int lp2 = 0; lp2 < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; lp2++ ) + { + f2me( cx[lp][lp2], &cx_fx[lp][lp2], &cx_e ); + cx_fx[lp][lp2] = L_shr( cx_fx[lp][lp2], max_e - cx_e ); + } + } + cx_e = max_e; + + max_e = 0; + for ( int lp = 0; lp < PARAM_MC_MAX_PARAMETER_BANDS; lp++ ) + { + for ( int lp2 = 0; lp2 < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; lp2++ ) + { + f2me( cx_imag[lp][lp2], &cx_imag_fx[lp][lp2], &cx_imag_e ); + max_e = s_max( cx_imag_e, max_e ); + } + } + + for ( int lp = 0; lp < PARAM_MC_MAX_PARAMETER_BANDS; lp++ ) + { + for ( int lp2 = 0; lp2 < PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS; lp2++ ) + { + f2me( cx_imag[lp][lp2], &cx_imag_fx[lp][lp2], &cx_imag_e ); + cx_imag_fx[lp][lp2] = L_shr( cx_imag_fx[lp][lp2], max_e - cx_imag_e ); + } + } + cx_imag_e = max_e; + + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot_fx( &hParamMC->Cldfb_RealBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + hParamMC->Cldfb_RealBuffer_tc_e, + &hParamMC->Cldfb_ImagBuffer_tc_fx[slot_idx * hParamMC->num_freq_bands * nchan_transport], + hParamMC->Cldfb_ImagBuffer_tc_e, + cx_fx, + &cx_e, + cx_imag_fx, + &cx_imag_e, + hParamMC, + nchan_transport ); + + for ( int lp = 0; lp < PARAM_MC_MAX_PARAMETER_BANDS; lp++ ) + { + me2f_buf( cx_fx[lp], cx_e, cx[lp], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + me2f_buf( cx_imag_fx[lp], cx_imag_e, cx_imag[lp], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + } + free( cx_fx ); + free( cx_imag_fx ); +#else ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], cx, cx_imag, hParamMC, nchan_transport ); +#endif } } @@ -2265,6 +2379,45 @@ static void remove_lfe_from_cy( return; } +#ifdef IVAS_FLOAT_FIXED +static void remove_lfe_from_cy_fx( + const Word16 nY, /* i : dimension of the covariance matrix */ + Word16 lfe_indices[PARAM_MC_LOCAL_SZ_LFE_MAP], /* i : LFE index */ + Word16 num_lfe, /* i : number of LFEs */ + Word32 *cy, /* i : covariance matrix */ + Word32 *cy_woLFE /* o : covariance matrix with LFE removed */ +) +{ + Word16 ch_idx1, ch_idx2; + Word16 lfe_idx1, lfe_idx2; + Word32 *ptrCy; + Word32 *ptrCy_out; + + ptrCy = cy; + ptrCy_out = cy_woLFE; + + FOR ( lfe_idx1 = 0; lfe_idx1 < num_lfe + 1; lfe_idx1++ ) + { + FOR ( ch_idx1 = lfe_indices[lfe_idx1] + 1; ch_idx1 < lfe_indices[lfe_idx1 + 1]; ch_idx1++ ) + { + FOR ( lfe_idx2 = 0; lfe_idx2 < num_lfe + 1; lfe_idx2++ ) + { + FOR ( ch_idx2 = lfe_indices[lfe_idx2] + 1; ch_idx2 < lfe_indices[lfe_idx2 + 1]; ch_idx2++ ) + { + *( ptrCy_out++ ) = *( ptrCy++ ); + move32(); + } + ptrCy++; + } + ptrCy--; + } + ptrCy += nY; + } + + return; +} +#endif + /*------------------------------------------------------------------------- * ivas_param_mc_get_mixing_matrices() @@ -2386,6 +2539,58 @@ static void ivas_param_mc_get_mixing_matrices( } } +#ifdef IVAS_FLOAT_FIXED + Word16 matSize = MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS; + Word16 *icld_q_fx; + Word16 *icc_q_fx; + Word32 *Cx_state_fx; + Word16 Cx_state_e; + Word32 *Cproto_fx; + Word16 Cproto_e; + Word32 *Cy_state_fx; + Word16 Cy_state_e; + + icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( Word16 ) ); + icc_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe * sizeof( Word16 ) ); + + Cx_state_fx = (Word32 *) malloc( PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS * sizeof( Word32 ) ); + Cproto_fx = (Word32 *) malloc( MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS * sizeof( Word32 ) ); + Cy_state_fx = (Word32 *) malloc( MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS * sizeof( Word32 ) ); + + f2me_buf( Cx_state, Cx_state_fx, &Cx_state_e, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + f2me_buf( Cproto, Cproto_fx, &Cproto_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + + set32_fx( Cy_state_fx, 0, matSize ); + Cy_state_e = 0; + + if ( synth_config == PARAM_MC_SYNTH_LS_CONV_COV ) + { + f2me_buf( hParamMC->ls_conv_dmx_matrix, hParamMC->ls_conv_dmx_matrix_fx, &hParamMC->ls_conv_dmx_e, nY_cov * nY_intern ); + } + + floatToFixed_arr( hParamMC->icld_q, icld_q_fx, 8, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); + for ( int lp = 0; lp < hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; lp++ ) + { + icc_q_fx[lp] = (Word16)(hParamMC->icc_q[lp] * 32767); + } + + ivas_param_mc_dequantize_cov_fx( hParamMC, + icld_q_fx + param_band_idx * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe, + icc_q_fx + param_band_idx * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe, + param_band_idx, nY_cov, + synth_config, + nY_intern, + nX, Cx_state_fx, Cx_state_e, Cproto_fx, Cproto_e, Cy_state_fx, &Cy_state_e ); + + me2f_buf( Cy_state_fx, Cy_state_e, Cy_state, nY_intern * nY_intern ); + // dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state_fx.txt"); + + free( icld_q_fx ); + free( icc_q_fx ); + free( Cx_state_fx ); + free( Cproto_fx ); + free( Cy_state_fx ); +#else ivas_param_mc_dequantize_cov( hParamMC, hParamMC->icld_q + param_band_idx * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe, hParamMC->icc_q + param_band_idx * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe, @@ -2393,6 +2598,8 @@ static void ivas_param_mc_get_mixing_matrices( synth_config, nY_intern, nX, Cx_state, Cproto, Cy_state ); + //dbgwrite2_txt(Cy_state_fx,nY_intern*nY_intern,"../cy_state.txt"); +#endif /* Smoothing: Sum over two buffers */ if ( hParamMC->hMetadataPMC->bAttackPresent ) @@ -2415,7 +2622,24 @@ static void ivas_param_mc_get_mixing_matrices( /* remove LFE if necessary */ if ( remove_lfe ) { +#ifdef IVAS_FLOAT_FIXED + Word32 *Cy_full_fx = (Word32 *) malloc( MAX_CICP_CHANNELS * MAX_CICP_CHANNELS * sizeof( Word32 ) ); + Word16 Cy_full_e; + Word32 *Cy_fx = (Word32 *) malloc( MAX_CICP_CHANNELS * MAX_CICP_CHANNELS * sizeof( Word32 ) ); + Word16 Cy_e; + + f2me_buf( Cy_full, Cy_full_fx, &Cy_full_e, nY_cov*nY_cov ); + Cy_e = Cy_full_e; + + remove_lfe_from_cy_fx( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full_fx, Cy_fx ); + + me2f_buf( Cy_fx, Cy_e, Cy, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + + free( Cy_full_fx ); + free( Cy_fx ); +#else remove_lfe_from_cy( nY_cov, lfe_indices, hSynthesisOutputSetup->num_lfe, Cy_full, Cy ); +#endif } else { @@ -2821,6 +3045,7 @@ static void ivas_param_mc_dequantize_cov( } Nrqq[h_ild_mapping->ild_index[k]] = powf( 10.0f, ild_q[k] / 10.0f ) * hParamMC->hMetadataPMC->ild_factors[k] * ref_ener; } + //dbgwrite2_txt(Nrqq,size,"../nrqq.txt"); /* estimate ICCs from estimated Cproto */ for ( k = 0; k < nY_int; k++ ) @@ -2931,6 +3156,324 @@ static void ivas_param_mc_dequantize_cov( return; } +#ifdef IVAS_FLOAT_FIXED + +/*------------------------------------------------------------------------- + * ivas_param_mc_dequantize_cov_fx() + * + * generate the target covariance matrix + *------------------------------------------------------------------------*/ + +static void ivas_param_mc_dequantize_cov_fx( + PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ + Word16 *ild_q_fx, /* i : sequence of dequantized ILD values Q8 */ + Word16 *icc_q_fx, /* i : sequence of dequantized ICC values Q15*/ + const Word16 param_band_index, /* i : current parameter band */ + const Word16 nY_cov, /* i : number of output channels in the covariance synthesis */ + const PARAM_MC_SYNTHESIS_CONF synth_conf, /* i : Parametric MC synthesis configuration */ + const Word16 nY_int, /* i : number of channels in the transported format */ + const Word16 nX, /* i : number of transport channels */ + Word32 *Cx_state_fx, /* i : transport channel covariance matrix */ + Word16 Cx_state_e, /* i : exponent for transport channel covariance matrix */ + Word32 *Cproto_fx, /* i : prototype matrix */ + Word16 Cproto_e, /* i : exponent for prototype matrix */ + Word32 *Cy_state_fx, /* o : target covariance matrix */ + Word16 *Cy_state_e /* o : exponent for target covariance matrix */ +) +{ + Word16 Cy_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word16 Cp_buf_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + + Word32 Nrqq_fx[MAX_OUTPUT_CHANNELS]; + Word16 Nrqq_e[MAX_OUTPUT_CHANNELS]; + Word32 a_fx[MAX_OUTPUT_CHANNELS]; + Word16 a_e[MAX_OUTPUT_CHANNELS]; + Word16 k; + Word16 l; + Word32 *Cyp_fx; + Word16 *Cyp_e; + Word32 ap_fx; + Word16 ap_e; + Word16 param_frame_idx; + Word32 L_tmp; + Word16 tmp, tmp_e; + const PARAM_MC_ILD_MAPPING *h_ild_mapping; + Word32 Cy_state_int_fx[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + Word16 Cy_state_int_e[MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS]; + + set16_fx( Cp_buf_e, Cproto_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + + param_frame_idx = hParamMC->hMetadataPMC->param_frame_idx; + set32_fx( Nrqq_fx, 0, MAX_OUTPUT_CHANNELS ); + set16_fx( Nrqq_e, 0, MAX_OUTPUT_CHANNELS ); + h_ild_mapping = hParamMC->hMetadataPMC->ild_mapping_conf; + + /*get back Nrg*/ + tmp = 0; + + FOR( k = 0; k < nY_int; k++ ) + { + Word32 ref_ener_fx = 0; + Word16 ref_ener_e = 0; + Word16 ref_channel_cnt; + Word16 ref_channel_idx; + + FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ ) + { + ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; + ref_ener_fx = BASOP_Util_Add_Mant32Exp( Cx_state_fx[ref_channel_idx + ref_channel_idx * nX], Cx_state_e, ref_ener_fx, ref_ener_e, &ref_ener_e ); + } + + L_tmp = Mpy_32_16_1( 713378626, ild_q_fx[k] ); /*Q24 : L_tmp Q31 for log2(10)/10 -> 713378626 */ + L_tmp = BASOP_util_Pow2( L_tmp, 31 - 24, &tmp_e ); /*powf( 10.0f, ild_q_fx[k] / 10.0f )*/ + L_tmp = Mpy_32_32( L_tmp, Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC->ild_factors_fx[k] ) ); + + Nrqq_fx[h_ild_mapping->ild_index[k]] = L_tmp; + move32(); + Nrqq_e[h_ild_mapping->ild_index[k]] = add( tmp_e, ref_ener_e ); + move16(); + } + + /* estimate ICCs from estimated Cproto */ + + FOR( k = 0; k < nY_int; k++ ) + { + // a_fx[k] = 1.f / ( sqrtf( Cproto_fx[k + nY_int * k] ) + EPSILON ); + tmp_e = Cp_buf_e[k + nY_int * k]; + move16(); + + IF( NE_32(Cproto_fx[k + nY_int * k] , 0) ) + { + L_tmp = ISqrt32( Cproto_fx[k + nY_int * k], &tmp_e ); + } + ELSE + { + L_tmp = INV_EPSILON_MANT; + move32(); + tmp_e = 15; + move16(); + } + a_fx[k] = L_tmp; + move32(); + a_e[k] = tmp_e; + move16(); + + FOR( l = 0; l < nY_int; l++ ) + { + Cy_state_int_fx[k * nY_int + l] = Mpy_32_32( Cproto_fx[k * nY_int + l], a_fx[k] ); + move32(); + Cy_state_int_e[k * nY_int + l] = add( Cp_buf_e[k * nY_int + l], a_e[k] ); + move16(); + } + } + + FOR( k = 0; k < nY_int; k++ ) + { + Cyp_fx = Cy_state_int_fx + k; + Cyp_e = Cy_state_int_e + k; + ap_fx = a_fx[k]; + move32(); + ap_e = a_e[k]; + move16(); + + FOR( l = 0; l < nY_int; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + *Cyp_e = add( *Cyp_e, ap_e ); + + Cyp_fx += nY_int; + Cyp_e += nY_int; + } + } + + /*normalizing the Cy_state_int_fx to a common exponent*/ + + /* replace some estimated ICCs with transmitted values */ + FOR( k = 0; k < hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe; k++ ) + { + Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][0] + nY_int * hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][1]] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); + move32(); + Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][0] + nY_int * hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][1]] = tmp; + move16(); + Cy_state_int_fx[hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][1] + nY_int * hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][0]] = L_shr( L_deposit_h( icc_q_fx[k] ), tmp ); + move32(); + Cy_state_int_e[hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][1] + nY_int * hParamMC->hMetadataPMC->icc_mapping[param_frame_idx][k][0]] = tmp; + move16(); + } + + test(); + test(); + IF( GE_16(param_band_index , PARAM_MC_MAX_BAND_LFE) || EQ_16(hParamMC->hMetadataPMC->lfe_on,0) ) + { + FOR( k = 0; k < nY_int; k++ ) + { + Cy_state_int_fx[k + 3 * nY_int] = ONE_IN_Q31; + move32(); + Cy_state_int_e[k + 3 * nY_int] = 0; + move16(); + Cy_state_int_fx[3 + k * nY_int] = ONE_IN_Q31; + move32(); + Cy_state_int_e[3 + k * nY_int] = 0; + move16(); + } + Nrqq_fx[3] = 0; + move32(); + } + + /* Generate back Covariance Mtx */ + FOR( k = 0; k < nY_int; k++ ) + { + tmp_e = Nrqq_e[k]; + move16(); + a_fx[k] = Sqrt32( Nrqq_fx[k], &tmp_e ); + move32(); + a_e[k] = tmp_e; + move16(); + + /* v_multc( Cy_state_int_fx + k * nY_int, a_fx[k], Cy_state_int_fx + k * nY_int, nY_int ) */ + FOR( l = 0; l < nY_int; l++ ) + { + Cy_state_int_fx[k * nY_int + l] = Mpy_32_32( Cy_state_int_fx[k * nY_int + l], a_fx[k] ); + move32(); + Cy_state_int_e[k * nY_int + l] = add( Cy_state_int_e[k * nY_int + l], a_e[k] ); + move16(); + } + } + + FOR( k = 0; k < nY_int; k++ ) + { + Cyp_fx = Cy_state_int_fx + k; + Cyp_e = Cy_state_int_e + k; + ap_fx = a_fx[k]; + move32(); + ap_e = a_e[k]; + move16(); + + FOR( l = 0; l < nY_int; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + ( *Cyp_e ) = add( *Cyp_e, ap_e ); + + Cyp_fx += nY_int; + Cyp_e += nY_int; + } + } + + IF( synth_conf == PARAM_MC_SYNTH_LS_CONV_COV ) + { + /* Cy = dmx*Cy*dmx' */ + Word32 mat_mult_buffer1_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word16 mat_mult_buffer1_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word32 target_ch_ener_fx[MAX_CICP_CHANNELS]; + Word16 target_ch_ener_e[MAX_CICP_CHANNELS]; + Word32 dmx_ch_ener_fx[MAX_CICP_CHANNELS]; + + Word16 ls_conv_dmx_matrix_e[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + + set32_fx( target_ch_ener_fx, 0, MAX_CICP_CHANNELS ); + set16_fx( target_ch_ener_e, 0, MAX_CICP_CHANNELS ); + set32_fx( dmx_ch_ener_fx, 0, MAX_CICP_CHANNELS ); + set16_fx( ls_conv_dmx_matrix_e, hParamMC->ls_conv_dmx_e, MAX_OUTPUT_CHANNELS * MAX_OUTPUT_CHANNELS ); + + matrix_product_mant_exp( hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 0, + Cy_state_int_fx, Cy_state_int_e, nY_int, nY_int, 0, + mat_mult_buffer1_fx, mat_mult_buffer1_e ); + + matrix_product_mant_exp( mat_mult_buffer1_fx, mat_mult_buffer1_e, nY_cov, nY_int, 0, + hParamMC->ls_conv_dmx_matrix_fx, ls_conv_dmx_matrix_e, nY_cov, nY_int, 1, + Cy_state_fx, Cy_buf_e ); + + FOR( k = 0; k < nY_cov; k++ ) + { + FOR( l = 0; l < nY_int; l++ ) + { + L_tmp = Mpy_32_32( hParamMC->ls_conv_dmx_matrix_fx[k + l * nY_cov], Nrqq_fx[l] ); + tmp_e = add( ls_conv_dmx_matrix_e[k + l * nY_cov], Nrqq_e[l] ); + L_tmp = BASOP_Util_Add_Mant32Exp( target_ch_ener_fx[k], target_ch_ener_e[k], L_tmp, tmp_e, &tmp_e ); + target_ch_ener_fx[k] = L_tmp; + move32(); + target_ch_ener_e[k] = tmp_e; + move16(); + } + + dmx_ch_ener_fx[k] = Cy_state_fx[k + nY_cov * k]; + move32(); + + IF( dmx_ch_ener_fx[k] < 0.0f ) + { + Cy_state_fx[k + nY_cov * k] = L_negate( Cy_state_fx[k + nY_cov * k] ); + move32(); + dmx_ch_ener_fx[k] = L_negate( dmx_ch_ener_fx[k] ); + move32(); + } + + IF( extract_h( dmx_ch_ener_fx[k] ) == 0 ) + { + target_ch_ener_fx[k] = 0; + move32(); + target_ch_ener_e[k] = 0; + move16(); + } + ELSE + { + BASOP_Util_Divide_MantExp( extract_h( target_ch_ener_fx[k] ), target_ch_ener_e[k], extract_h( dmx_ch_ener_fx[k] ), Cy_buf_e[k + nY_cov * k], &tmp, &tmp_e ); + tmp = Sqrt16( tmp, &tmp_e ); + target_ch_ener_fx[k] = L_deposit_h( tmp ); + move32(); + target_ch_ener_e[k] = tmp_e; + move16(); + } + + FOR( l = 0; l < nY_cov; l++ ) + { + Cy_state_fx[k * nY_cov + l] = Mpy_32_32( target_ch_ener_fx[k], Cy_state_fx[k * nY_cov + l] ); + move32(); + Cy_buf_e[k * nY_cov + l] = add( target_ch_ener_e[k], Cy_buf_e[k * nY_cov + l] ); + move16(); + } + + Cyp_fx = Cy_state_fx + k; + Cyp_e = Cy_buf_e + k; + ap_fx = target_ch_ener_fx[k]; + move32(); + ap_e = target_ch_ener_e[k]; + move16(); + FOR( l = 0; l < nY_cov; l++ ) + { + ( *Cyp_fx ) = Mpy_32_32( *Cyp_fx, ap_fx ); + *Cyp_e = add( *Cyp_e, ap_e ); + + Cyp_fx += nY_cov; + Cyp_e += nY_cov; + } + } + } + ELSE + { + Copy32( Cy_state_int_fx, Cy_state_fx, nY_int * nY_int ); + Copy( Cy_state_int_e, Cy_buf_e, nY_int * nY_int ); + } + + /*normalize output matrix to a common exponent*/ + tmp = 0; + FOR( k = 0; k < nY_int * nY_int; k++ ) + { + Cy_state_fx[k] = BASOP_Util_Add_Mant32Exp( Cy_state_fx[k], Cy_buf_e[k], 0, 0, &Cy_buf_e[k] ); + move32(); + tmp = s_max( tmp, Cy_buf_e[k] ); + } + FOR( k = 0; k < nY_int * nY_int; k++ ) + { + L_tmp = L_shr( Cy_state_fx[k], tmp - Cy_buf_e[k] ); + Cy_state_fx[k] = L_tmp; + move32(); + } + *Cy_state_e = tmp; + move16(); + + return; +} +#endif /*-------------------------------------------------------------------------* * param_mc_set_num_synth_bands() diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 8d8612a5b6af08867d647737b0d034cb6098a308..5053c03efc8838f7474520cbb636605a05c772da 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -701,6 +701,12 @@ typedef struct ivas_param_mc_dec_data_structure int16_t slot_size; float *Cldfb_RealBuffer_tc; float *Cldfb_ImagBuffer_tc; +#ifdef IVAS_FLOAT_FIXED + Word32 *Cldfb_RealBuffer_tc_fx; + Word16 Cldfb_RealBuffer_tc_e; + Word32 *Cldfb_ImagBuffer_tc_fx; + Word16 Cldfb_ImagBuffer_tc_e; +#endif int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; int16_t nb_subframes; int16_t subframes_rendered; @@ -730,9 +736,17 @@ typedef struct ivas_param_mc_dec_data_structure HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC; float *icc_q; /* ICC parameters*/ float *icld_q; +#ifdef IVAS_FLOAT_FIXED + Word16 *icc_q_fx; /* ICC parameters*/ + Word16 *icld_q_fx; +#endif int16_t max_param_band_abs_cov; float *ls_conv_dmx_matrix; float *proto_matrix_int; +#ifdef IVAS_FLOAT_FIXED + Word32 *ls_conv_dmx_matrix_fx; + Word16 ls_conv_dmx_e; +#endif /*sub-modules*/ HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params;