diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 27ed4cabd3d2889da3b915c650087c2f24f89d7b..3a1a8abaff783e2b068dbeca085b5291379d7349 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -176,6 +176,14 @@ Word32 BASOP_Util_InvLog2( Word32 x ) Word32 BASOP_Util_Log10( Word32 x, Word16 e ) { + test(); + IF( e >= 0 && LE_16( e, 31 ) ) + { + IF( EQ_32( x, L_shl_sat( 1, sub( 31, e ) ) ) ) + { + return 0; + } + } Word32 res = BASOP_Util_Log2( x ); res = L_add( Mpy_32_32( res, 646456993 /* log10(2) in Q31 */ ), Mpy_32_32( L_shl( e, 25 ), 646456993 /* log10(2) in Q31 */ ) ); // Adjusting for the exponent mismatch: multiplying first so as to avoid saturation return res; diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 2dc3d9c762ae8fee56bd97a99dd0f6e34a196455..7ca1ddf813bbc7fd88c930a953288991d04d875e 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -115,7 +115,7 @@ static int16_t file_read_FECpattern( void ) * * insert a bit into packed octet *-------------------------------------------------------------------*/ -static void pack_bit( +void pack_bit( const Word16 bit, /* i: bit to be packed */ UWord8 **pt, /* i/o: pointer to octet array into which bit will be placed */ UWord8 *omask /* i/o: output mask to indicate where in the octet the bit is to be written */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 1d2056c8c96b4795eee62aca549c589ac0ce026f..ea13117e52b54aa70131bd893c71a7d76b595131 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1795,6 +1795,16 @@ void stereo_dft_cng_side_gain( const int16_t bwidth /* i : audio band-width */ ); +#ifdef IVAS_FLOAT_FIXED +void stereo_dft_quantize_res_gains_fx( + const Word32 *g, //Q31 + const Word32 *r, //Q31 + Word32 *gq, //Q31 + Word32 *rq, //Q31 + Word16 *ig, + Word16 *ir); +#endif + void stereo_dft_quantize_res_gains( const float *g, const float *r, @@ -2239,9 +2249,9 @@ void stereo_dft_hybrid_ITD_flag( void stereo_dft_enc_compute_itd_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ Word32 *DFT_L, - Word16 DFT_L_e, + Word16 *DFT_L_e, Word32 *DFT_R, - Word16 DFT_R_e, + Word16 *DFT_R_e, const Word16 k_offset, const Word16 input_frame, const Word16 vad_flag_dtx[], @@ -4081,9 +4091,7 @@ void getChannelEnergies( void mctStereoIGF_enc_fx( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ -#endif Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ @@ -4095,8 +4103,7 @@ void mctStereoIGF_enc_fx( #endif const Word16 sp_aud_decision0[MCT_MAX_CHANNELS] /* i : speech audio decision */ ); -#endif // IVAS_FLOAT_FIXED - +#endif void mctStereoIGF_enc( MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ Encoder_State **sts, /* i/o: encoder state structure */ diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 5018b001ad6208fcf6499271c6d1d82eb787478d..4b9d3984237cb96c900c7ccfde32eaf50212c571 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -69,10 +69,12 @@ const int16_t dft_band_limits_erb8[STEREO_DFT_ERB8_BANDS] = 1, 5, 18, 41, 84, 214, 470, 601 }; +#ifndef IVAS_FLOAT_FIXED const float dft_res_cod_alpha[STEREO_DFT_BAND_MAX] = { .8f, .8f, .5f, .5f, .3f, .3f, .2f, .2f }; +#endif const int16_t dft_band_ipd[3][4] = { @@ -88,6 +90,171 @@ const int16_t dft_band_res_cod[3][4] = {0,5,6,7} }; +const Word32 dft_res_gains_q_Q31[][2] = +{ + /* quantization points for joint quantization of prediction gain and residual energy */ + + /* column 1 (|ILD| = 0): */ + {0, 0 }, + {0, 251216928 }, + {0, 487459456 }, + {0, 731632640 }, + {0, 997611392 }, + {0, 1299397248 }, + {0, 1666984192 }, + {0, 2147483647 }, + + /* column 2 (|ILD| = 2): */ + {246151024, 0 }, + {249475328, 247871152 }, + {258660112, 480729248 }, + {274304544, 720918848 }, + {298427200, 981720000 }, + {334663840, 1276185088 }, + {391374592, 1632160640 }, + {485919712, 2091786496 }, + + /* column 3 (|ILD| = 4): */ + {485919712, 0 }, + {492224736, 238188144 }, + {509610752, 461283776 }, + {539117184, 690072384 }, + {584326016, 936189056 }, + {651608832, 1210182144 }, + {755411712, 1534299776 }, + {924504576, 1938292992 }, + + /* column 4 (|ILD| = 6): */ + {713563712, 0 }, + {722237376, 223142880 }, + {746085184, 431184640 }, + {786311872, 642617280 }, + {847364864, 866812416 }, + {936938496, 1111020032 }, + {1072199936, 1390431232 }, + {1285225984, 1720430720 }, + + /* column 5 (|ILD| = 8): */ + {924504576, 0 }, + {934784576, 204139792 }, + {962942400, 393358880 }, + {1010083968, 583482048 }, + {1080789888, 781462848 }, + {1182728704, 991308544 }, + {1332741248, 1221608960 }, + {1559902080, 1475937536 }, + + /* column 6 (|ILD| = 10): */ + {1115604864, 0 }, + {1126709504, 182744416 }, + {1156997632, 351025536 }, + {1207276672, 517958016 }, + {1281710592, 688294272 }, + {1387005952, 863412992 }, + {1537761536, 1046870336 }, + {1757032448, 1234717184 }, + + /* column 7 (|ILD| = 13): */ + {1361843968, 0 }, + {1372924928, 149366080 }, + {1402942464, 285507936 }, + {1452130560, 417893888 }, + {1523515136, 548787328 }, + {1621670144, 677135936 }, + {1756740352, 802203264 }, + {1942499840, 915633344 }, + + /* column 8 (|ILD| = 16): */ + {1559902080, 0 }, + {1569913600, 117815248 }, + {1596862336, 224162928 }, + {1640492800, 325650848 }, + {1702660352, 423060736 }, + {1785997696, 514412544 }, + {1896788608, 597466432 }, + {2042241920, 664027712 }, + + /* column 9 (|ILD| = 19): */ + {1714196608, 0 }, + {1722634112, 90359672 }, + {1745223424, 171238192 }, + {1781415040, 247171072 }, + {1832190080, 318199104 }, + {1898830848, 382271424 }, + {1984989952, 437025792 }, + {2094086528, 475912448 }, + + /* column 10 (|ILD| = 22): */ + {1831427712, 0 }, + {1838194432, 67828272 }, + {1856228992, 128123168 }, + {1884882944, 183977072 }, + {1924581248, 235132272 }, + {1975822336, 279821408 }, + {2040659200, 316058048 }, + {2120554240, 339023232 }, + + /* column 11 (|ILD| = 25): */ + {1918819584, 0 }, + {1924055168, 50102940 }, + {1937964416, 94399088 }, + {1959916032, 135003712 }, + {1990038784, 171579648 }, + {2028424960, 202728896 }, + {2076217216, 226931040 }, + {2133943808, 240762976 }, + + /* column 12 (|ILD| = 30): */ + {2015827840, 0 }, + {2019068416, 29502130 }, + {2027636864, 55420112 }, + {2041056512, 78889960 }, + {2059271424, 99626064 }, + {2082150784, 116769424 }, + {2110128128, 129415952 }, + {2143192960, 135682304 }, + + /* column 13 (|ILD| = 35): */ + {2072441984, 0 }, + {2074364032, 17033840 }, + {2079438464, 31939524 }, + {2087347712, 45337676 }, + {2098012032, 57039312 }, + {2111296384, 66537632 }, + {2127368192, 73321536 }, + {2146126464, 76351632 }, + + /* column 14 (|ILD| = 40): */ + {2104959232, 0 }, + {2106073728, 9723806 }, + {2109011456, 18212808 }, + {2113579136, 25810606 }, + {2119712384, 32401234 }, + {2127314432, 37692632 }, + {2136458496, 41399188 }, + {2147054208, 42945376 }, + + /* column 15 (|ILD| = 45): */ + {2123466240, 0 }, + {2124103936, 5514738 }, + {2125783296, 10322954 }, + {2128390400, 14615774 }, + {2131882240, 18322330 }, + {2136200832, 21283710 }, + {2141376256, 23332410 }, + {2147348352, 24150602 }, + + /* column 16 (|ILD| = 50): */ + {2133943808, 0 }, + {2134306688, 3115998 }, + {2135260160, 5830418 }, + {2136737664, 8250632 }, + {2138715520, 10335839 }, + {2141157120, 11995844 }, + {2144077696, 13136157 }, + {2147440640, 13580687 } +}; + const float dft_res_gains_q[][2] = { /* quantization points for joint quantization of prediction gain and residual energy */ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 1a043780a2fa8b8ac3bc1440f65cfb91d9228116..679dbe800b411b84005d7c24109f6bc95281f672 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -57,7 +57,9 @@ extern const int16_t dft_band_ipd[3][4]; extern const int16_t dft_band_res_cod[3][4]; extern const float dft_res_gains_q[][2]; +#ifndef IVAS_FLOAT_FIXED extern const float dft_res_cod_alpha[STEREO_DFT_BAND_MAX]; +#endif extern const float dft_trigo_12k8[STEREO_DFT_N_12k8_ENC / 4 + 1]; extern const float dft_trigo_32k[STEREO_DFT_N_32k_ENC / 4 + 1]; diff --git a/lib_com/prot.h b/lib_com/prot.h index 3417fa83e483dc68fa9a45e45e2c4d1154306577..27b358b7f38375313aaffbe6387cb63402499701 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -10012,11 +10012,13 @@ void IGFEncApplyStereo( const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); +#ifndef IVAS_FLOAT_FIXED void IGFEncConcatenateBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ const int16_t bsBits, /* i : number of IGF bits written to list of indices */ BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ ); +#endif // !IVAS_FLOAT_FIXED void IGFEncResetTCX10BitCounter( const IGF_ENC_INSTANCE_HANDLE hIGFEnc /* i : instance handle of IGF Encoder */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index dc75804b3e7dd002f5564a059fa8a0ec98628bbb..da94afae5ce957e7b9a895f69ceb21724c750ddc 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -238,6 +238,27 @@ void deindex_lvq_SHB_fx( const Word16 nbits, const Word16 mode ); +Word32 encode_comb_fx( Word16 *cv, Word16 idx_lead ); + +Word32 mslvq_ivas_16( + Word16 *pTmp_fx, /* i : M-dimensional input vector */ + Word16 *quant_fx, /* o : quantized vector */ + Word16 *cv_out_fx, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ + Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ + Word16 *idx_scale, /* o : scale index for each subvector */ + const Word16 *w_fx, /* i : weights for LSF quantization */ + const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ + const Word16 mode_glb, /* i : LVQ coding mode */ + const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ +); + +UWord32 index_lvq_SHB_fx( + const Word16 idx_lead, + const Word16 idx_scale, + const Word16 nbits, + Word16 *lat_cv, + const Word16 mode ); + Word16 deindex_lvq_ivas_fx( Word16 *index, /* i : index to be decoded, as an array of 3 Word16 */ Word16 *x_lvq, /* o : decoded codevector Q(x2.56) */ @@ -10233,23 +10254,15 @@ Word32 sum2_32_fx( #ifdef IVAS_FLOAT_FIXED void ProcessStereoIGF_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ -#if 1 -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ -#endif + Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ + Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ + Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ -#endif - float *pITFMDCTSpectrum[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subfr. */ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate /* i : element bitrate */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate /* i : element bitrate */ ); /*igf_enc.c*/ void IGFEncApplyStereo_fx( @@ -10301,6 +10314,16 @@ Word16 ari_encode_14bits_sign( Tastat *s, Word16 sign ); Word16 ari_done_encoding_14bits( Word16 *ptr, Word16 bp, Tastat *s ); +void pack_bit( + const Word16 bit, /* i: bit to be packed */ + UWord8 **pt, /* i/o: pointer to octet array into which bit will be placed */ + UWord8 *omask /* i/o: output mask to indicate where in the octet the bit is to be written */ +); +void IGFEncConcatenateBitstream( + const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ + const Word16 bsBits, /* i : number of IGF bits written to list of indices */ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +); #endif // IVAS_FLOAT_FIXED #endif diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 4b29fbfbd5b4b1a042f721ed3a38c3f462b7fe3a..0d44884991e1c1fd02a4b3e16701d993a45f544a 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -38615,12 +38615,6 @@ const Word32 sigma_BWE_fx[] = { 19499580, 20916386, 22705246, 39204284, 40792208 }; /* for 3 bits first stage */ -const Word16 sigma_BWE16_fx[] = { -260, 255, 268, -267, 294, 315, 598, -622, 289, 288, 297, -298, 319, 346, 598, -622 }; /* for 3 bits first stage */ const float inv_sigma_BWE[] = { 126.2392994665869f, 128.5766227364854f, 122.2856952550425f, 122.8889356808437f, 111.5502335749417f, @@ -38629,6 +38623,44 @@ const float inv_sigma_BWE[] = { 94.5809450935691f, 54.7767591108706f, 52.6444584512409f /* for 3 bits fiest stage */ }; + +const Word16 inv_modified_sigma_BWE_fx[] = { + 259, +254, +267, +266, +293, +315, +598, +622, +288, +288, +297, +297, +319, +346, +598, +622 +}; + +const Word16 modified_sigma_BWE_fx[] = +{ 323, +329, +313, +314, +285, +266, +140, +134, +290, +290, +282, +281, +262, +242, +140, +134 }; + const float SHB_LSF_mean[10] = { 0.04131f, 0.08078f, 0.12348f, 0.16567f, 0.21045f, 0.25449f, 0.30101f, 0.34693f, 0.39605f, 0.44428f }; @@ -38712,6 +38744,18 @@ const Word16 scales_BWE_fx[] = { 24592, 6955, 14491, 26427 }; +const Word16 scales_BWE_fx_new[] = { + +1908, +3434, +5756, +1824, +3624, +6148, +1738, +3622, +6606 +}; const Word8 no_lead_BWE[] = { 8, 6, 5, /* 14 bits */ 10,9,5, /* 15 bits*/ @@ -38730,6 +38774,18 @@ const Word16 scales_BWE_3b_fx[] = { 21544, 7249, 12689, 23060 }; +const Word16 scales_BWE_3b_fx_new[] = { + 1961, +3565, +7233, +1902, +3192, +5386, +1812, +3172, +5765 +}; + const Word8 no_lead_BWE_3b[] = { 4, 5, 2, /* 12 bits */ 5, 5, 5, /* 13 bits */ diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index c5f5a5e0cb6985a77de4062f283f0d4dcd25b163..414185564aa9f58e1647800606d9c1f8680fdd7f 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -2008,14 +2008,17 @@ extern const Word16 tcx_mdct_window_trans_48_fx[60]; extern const float sigma_BWE[]; extern const Word32 sigma_BWE_fx[]; -extern const Word16 sigma_BWE16_fx[]; extern const float inv_sigma_BWE[]; +extern const Word16 inv_modified_sigma_BWE_fx[]; +extern const Word16 modified_sigma_BWE_fx[]; extern const float scales_BWE[]; extern const Word8 no_lead_BWE[]; extern const float scales_BWE_3b[]; extern const Word16 scales_BWE_fx[]; +extern const Word16 scales_BWE_fx_new[]; extern const Word16 scales_BWE_3b_fx[]; +extern const Word16 scales_BWE_3b_fx_new[]; extern const Word8 no_lead_BWE_3b[]; extern const int16_t mslvq_SHB_min_bits[]; diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index c9130877094380f5d42b38e62014f550d116f764..b63ba4e8ee6e40de3ef80e71d0d9b95c57aa1c0c 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -18,6 +18,7 @@ *---------------------------------------------------------------------------*/ #define HLM_MIN_NRG 32768.0f +#define HLM_MIN_NRG_FX 32768 /*Q0*/ #define MAX_SUBDIVISIONS 3 @@ -500,15 +501,14 @@ Word16 ITF_Detect_ivas_fx( Word32 L_tmp, tmp32; Word16 tmpbuf[325]; Word16 n, i; + Word32 norms[MAX_SUBDIVISIONS]; + Word16 norms_e[MAX_SUBDIVISIONS]; #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); #endif - move16(); - move16(); - move16(); - + set16_fx( norms_e, sub( 31, Q ), MAX_SUBDIVISIONS ); if ( maxOrder <= 0 ) { return 0; @@ -523,12 +523,12 @@ Word16 ITF_Detect_ivas_fx( iStartLine = imult1616( tmp, iSubdivisions ); iEndLine = add( iStartLine, tmp ); - if ( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); + IF( EQ_16( nSubdivisions, 3 ) ) + iStartLine = mult( iStartLine, 0x2AAB ); iStartLine = add( iStartLine, startLine ); - if ( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); + IF( EQ_16( nSubdivisions, 3 ) ) + iEndLine = mult( iEndLine, 0x2AAB ); iEndLine = add( iEndLine, startLine ); headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) ); /* Calculate norm of spectrum band */ @@ -561,11 +561,10 @@ Word16 ITF_Detect_ivas_fx( move16(); /* normalization not needed for one subdivision */ } - test(); - IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) ) + IF( L_tmp > 0 ) { - move16(); facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 ); + move16(); tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ @@ -574,6 +573,8 @@ Word16 ITF_Detect_ivas_fx( facs[iSubdivisions] = div_s( 0x2000, round_fx_o( L_tmp, &Overflow ) ); /* L_tmp is >= 0x2000000 */ move16(); } + norms[iSubdivisions] = sum2_32_fx( pSpectrum + sub( iStartLine, IGF_START_MN ), sub( iEndLine, iStartLine ), &norms_e[iSubdivisions] ); + move16(); } /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */ @@ -581,25 +582,20 @@ Word16 ITF_Detect_ivas_fx( spectrumLength = sub( stopLine, startLine ); - FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ ) + FOR( iSubdivisions = 0; ( iSubdivisions < nSubdivisions ) && GT_64( norms[iSubdivisions], W_shl( HLM_MIN_NRG_FX, sub( 31, norms_e[iSubdivisions] ) ) ); iSubdivisions++ ) { - IF( facs[iSubdivisions] == 0 ) - { - BREAK; - } - - + test(); assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); iStartLine = imult1616( spectrumLength, iSubdivisions ); iEndLine = add( iStartLine, spectrumLength ); - if ( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); + IF( EQ_16( nSubdivisions, 3 ) ) + iStartLine = mult( iStartLine, 0x2AAB ); iStartLine = add( iStartLine, startLine ); - if ( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); + IF( EQ_16( nSubdivisions, 3 ) ) + iEndLine = mult( iEndLine, 0x2AAB ); iEndLine = add( iEndLine, startLine ); @@ -614,7 +610,7 @@ Word16 ITF_Detect_ivas_fx( move16(); } - FOR( lag = 0; lag <= maxOrder; lag++ ) + FOR( lag = 1; lag <= maxOrder; lag++ ) { n = sub( sub( iEndLine, lag ), iStartLine ); @@ -635,8 +631,12 @@ Word16 ITF_Detect_ivas_fx( } } + *predictionGain = 0; + move16(); IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */ { + rxx[0] = 3 * ONE_IN_Q29; + move32(); /* Limit the maximum order to spectrum length/4 */ ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain ); diff --git a/lib_dec/FEC_HQ_phase_ecu_fx.c b/lib_dec/FEC_HQ_phase_ecu_fx.c index 1bd2387360d6c28b1244848bbb41d82b9674252f..77a82258b29b81a4e0c39619a9a9eaae5f06184c 100644 --- a/lib_dec/FEC_HQ_phase_ecu_fx.c +++ b/lib_dec/FEC_HQ_phase_ecu_fx.c @@ -3067,10 +3067,10 @@ static void ivas_rec_wtda_fx( tmp_e = 0; tmp = BASOP_Util_Divide1616_Scale( ONE_IN_Q14, *w_hamm, &tmp_e ); tmp = shl( tmp, 1 ); - tmp = shr( tmp, sub( 4, tmp_e ) ); // Q11 - *pX_start = mult_r( *pX_start, tmp ); // Qin - 4 + tmp = shr( tmp, sub( 4, tmp_e ) ); // Q11 + *pX_start = shl( mult_r( *pX_start, tmp ), 4 ); // Qin move16(); - *pX_end = mult_r( *pX_end, tmp ); // Qin - 4 + *pX_end = shl( mult_r( *pX_end, tmp ), 4 ); // Qin move16(); pX_start++; pX_end--; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 519a6c79b17da202cd93285f05a02f0c2bcae5f2..29ef2aa21ecba1cbb71bfba92cb41bbbeb0c70bb 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -3245,12 +3245,12 @@ void IGFEncSetMode( /*-------------------------------------------------------------------* - * pack_bit() + * pack_bit_ivas() * * insert a bit into packed octet *-------------------------------------------------------------------*/ - -static void pack_bit( +#ifndef IVAS_FLOAT_FIXED +static void pack_bit_ivas( const int16_t bit, /* i : bit to be packed */ uint8_t **pt, /* i/o: pointer to octet array into which bit will be placed */ uint8_t *omask /* i/o: output mask to indicate where in the octet the bit is to be written */ @@ -3275,7 +3275,7 @@ static void pack_bit( return; } - +#endif /*-------------------------------------------------------------------* * IGFEncConcatenateBitstream() @@ -3283,6 +3283,65 @@ static void pack_bit( * IGF bitstream concatenation for TCX10 modes *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void IGFEncConcatenateBitstream( + const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ + const Word16 bsBits, /* i : number of IGF bits written to list of indices */ + BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle */ +) +{ + Word16 i; + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + Indice *ind_list; + UWord8 *pFrame; /* byte array with bit packet and byte aligned coded speech data */ + Word16 *pFrame_size; /* number of bits in the binary encoded access unit [bits] */ + Word16 k, nb_bits_written; + Word32 imask; + UWord8 omask; + + hPrivateData = &hIGFEnc->igfData; + + ind_list = &hBstr->ind_list[sub( hBstr->nb_ind_tot, bsBits )]; /* here, we assume that each bit has been written as a single indice */ + pFrame = hPrivateData->igfBitstream; + pFrame_size = &hPrivateData->igfBitstreamBits; + nb_bits_written = 0; + move16(); + + omask = (UWord8) shr( 0x80, s_and( *pFrame_size, 0x7 ) ); + pFrame += shr( *pFrame_size, 3 ); + + /* bitstream packing (conversion of individual indices into a serial stream) */ + FOR( i = 0; i < bsBits; i++ ){ + IF( ind_list[i].nb_bits > 0 ){ + /* mask from MSB to LSB */ + imask = L_shl( 1, ( sub( ind_list[i].nb_bits, 1 ) ) ); + + /* write bit by bit */ + FOR( k = 0; k < ind_list[i].nb_bits; k++ ) + { + pack_bit( ind_list[i].value & imask, &pFrame, &omask ); + imask = L_shr( imask, 1 ); + } + nb_bits_written = add( nb_bits_written, ind_list[i].nb_bits ); + + /* delete the indice */ + ind_list[i].nb_bits = -1; + move16(); +} +} + +*pFrame_size = add( *pFrame_size, nb_bits_written ); +move16(); + +/* update list of indices */ +hBstr->nb_ind_tot = sub( hBstr->nb_ind_tot, bsBits ); +hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written ); +move16(); +move16(); + +return; +} +#else void IGFEncConcatenateBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ const int16_t bsBits, /* i : number of IGF bits written to list of indices */ @@ -3319,7 +3378,7 @@ void IGFEncConcatenateBitstream( /* write bit by bit */ for ( k = 0; k < ind_list[i].nb_bits; k++ ) { - pack_bit( ind_list[i].value & imask, &pFrame, &omask ); + pack_bit_ivas( ind_list[i].value & imask, &pFrame, &omask ); imask >>= 1; } nb_bits_written += ind_list[i].nb_bits; @@ -3337,6 +3396,7 @@ void IGFEncConcatenateBitstream( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index b0cdf76d25510978291a5ee3ef56920116976dc8..7b13bc2c9ea8ebbde2c00feb60516fa19da5e1aa 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -406,11 +406,12 @@ ivas_error ivas_cpe_enc( * Stereo processing * Stereo down-mix *----------------------------------------------------------------*/ - + // printf("\n%f %f ", hCPE->hStereoClassif->is_speech, hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0]); if ( hCPE->element_mode == IVAS_CPE_DFT ) { stereo_dft_hybrid_ITD_flag( hCPE->hStereoDft->hConfig, input_Fs, hCPE->hStereoDft->hItd->hybrid_itd_max ); #ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS /* flt2fix: to be removed */ FOR( int i = 0; i < CPE_CHANNELS; i++ ) { @@ -426,11 +427,11 @@ ivas_error ivas_cpe_enc( #endif // MSAN_FIX } floatToFixed_arrL( hCPE->hStereoDft->side_gain, hCPE->hStereoDft->side_gain_fx, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); - floatToFixed_arrL( hCPE->hStereoDft->res_pred_gain, hCPE->hStereoDft->res_pred_gain_fx, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); floatToFixed_arrL( hCPE->hStereoDft->gipd, hCPE->hStereoDft->gipd_fx, Q13, STEREO_DFT_ENC_DFT_NB ); floatToFixed_arrL( hCPE->hStereoDft->hItd->itd, hCPE->hStereoDft->hItd->itd_fx, Q16, STEREO_DFT_ENC_DFT_NB ); floatToFixed_arrL( hCPE->hStereoDft->hItd->deltaItd, hCPE->hStereoDft->hItd->deltaItd_fx, Q16, STEREO_DFT_ENC_DFT_NB ); /* flt2fix end */ +#endif /* Time Domain ITD compensation using extrapolation */ stereo_td_itd_fx( hCPE->hStereoDft->hItd, hCPE->hStereoDft->input_mem_itd_fx, hCPE->hStereoDft->q_input_mem_itd, hCPE->hStereoDft->hConfig->hybrid_itd_flag, hCPE->hStereoDft->dft_ovl, sts, input_frame, hCPE->input_mem_fx, hCPE->q_input_mem ); @@ -448,9 +449,9 @@ ivas_error ivas_cpe_enc( /* Update DFT Stereo memories */ stereo_dft_enc_update_fx( hCPE->hStereoDft, sts[0]->max_bwidth ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS /* fix2flt: to be removed */ fixedToFloat_arrL( hCPE->hStereoDft->side_gain_fx, hCPE->hStereoDft->side_gain, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); - fixedToFloat_arrL( hCPE->hStereoDft->res_pred_gain_fx, hCPE->hStereoDft->res_pred_gain, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); fixedToFloat_arrL( hCPE->hStereoDft->gipd_fx, hCPE->hStereoDft->gipd, Q13, STEREO_DFT_ENC_DFT_NB ); fixedToFloat_arrL( hCPE->hStereoDft->hItd->itd_fx, hCPE->hStereoDft->hItd->itd, Q16, STEREO_DFT_ENC_DFT_NB ); fixedToFloat_arrL( hCPE->hStereoDft->hItd->deltaItd_fx, hCPE->hStereoDft->hItd->deltaItd, Q16, STEREO_DFT_ENC_DFT_NB ); @@ -473,16 +474,15 @@ ivas_error ivas_cpe_enc( #endif // MSAN_FIX } /* fix2flt end */ - -#if 0 - /* flt2fix: to be removed */ - for ( int i = 0; i < CPE_CHANNELS; i++ ) - { - f2me_buf( hCPE->hStereoDft->DFT[i], hCPE->hStereoDft->DFT_fx[i], &hCPE->hStereoDft->DFT_fx_e[i], STEREO_DFT_N_MAX_ENC ); - } - /* flt2fix end */ #endif + /* DFT stereo processing */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /* flt2fix: to be removed */ + hCPE->hStereoDft->voicing_lt_fx = floatToFixed( hCPE->hStereoDft->voicing_lt, 31 ); + floatToFixed_arr( hCPE->hCoreCoder[0]->voicing, hCPE->hCoreCoder[0]->voicing_fx, 15, 3 ); + /* flt2fix end */ +#endif stereo_dft_enc_process( hCPE, vad_flag_dtx, vad_hover_flag, input_frame ); } else if ( hCPE->element_mode == IVAS_CPE_TD ) diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 775dbbfff6a22c275607f511202195fefaf79c2f..788eee3babaf9cbf6920859ec40480013d4cc154 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -357,7 +357,7 @@ void ivas_mct_core_enc( Word32 *inv_mdst_spectrum_fx[MCT_MAX_CHANNELS][2]; Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][2]; Word32 inv_spectrum_long_fx[MCT_MAX_CHANNELS][L_FRAME48k]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ -#endif // IVAS_FLOAT_FIXED +#endif int16_t ch, ch_core, nSubframes, L_subframeTCX; int16_t i, cpe_id, n, nAvailBits; int16_t nCPE; diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 26d36aff4624d7b2ea15874b9618f65408e4d7db..a0c1435b9305a158bf22ffb401f71250f9af2e1b 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -1598,11 +1598,9 @@ void write_mct_bitstream_fx( *--------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED void mctStereoIGF_enc_fx( - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - Encoder_State **sts, /* i/o: encoder state structure */ -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ -#endif + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + Encoder_State **sts, /* i/o: encoder state structure */ + Word32 *orig_spectrum_fx[MCT_MAX_CHANNELS][2], /* i : MDCT spectrum for ITF */ Word32 powerSpec_fx[MCT_MAX_CHANNELS][L_FRAME48k], /* i/o: MDCT^2 + MDST^2 spectrum,or estimate*/ Word32 *powerSpecMsInv_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : same as above but for inverse spect.*/ Word32 *inv_spectrum_fx[MCT_MAX_CHANNELS][NB_DIV], /* i : inverse spectrum */ @@ -1618,9 +1616,7 @@ void mctStereoIGF_enc_fx( #ifdef IVAS_FLOAT_FIXED Word32 *p_powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV]; Word32 *p_inv_spectrum_fx[CPE_CHANNELS][NB_DIV]; -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING Word32 *p_orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; -#endif Word32 *p_powerSpec_fx[NB_DIV]; #endif // IVAS_FLOAT_FIXED @@ -1629,7 +1625,6 @@ void mctStereoIGF_enc_fx( Encoder_State *p_st[NB_DIV]; Encoder_State *st; float *p_powerSpecMsInv[CPE_CHANNELS][NB_DIV]; - float *p_inv_spectrum[CPE_CHANNELS][NB_DIV]; float *p_orig_spectrum[CPE_CHANNELS][NB_DIV]; float *p_powerSpec[NB_DIV]; int16_t singleChEle[MCT_MAX_CHANNELS]; @@ -1678,13 +1673,9 @@ void mctStereoIGF_enc_fx( p_orig_spectrum[1][n] = orig_spectrum[ch2][n]; p_powerSpecMsInv[0][n] = powerSpecMsInv[ch1][n]; p_powerSpecMsInv[1][n] = powerSpecMsInv[ch2][n]; - p_inv_spectrum[0][n] = inv_spectrum[ch1][n]; - p_inv_spectrum[1][n] = inv_spectrum[ch2][n]; #endif -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING p_orig_spectrum_fx[0][n] = orig_spectrum_fx[ch1][n]; p_orig_spectrum_fx[1][n] = orig_spectrum_fx[ch2][n]; -#endif p_powerSpecMsInv_fx[0][n] = powerSpecMsInv_fx[ch1][n]; p_powerSpecMsInv_fx[1][n] = powerSpecMsInv_fx[ch2][n]; p_inv_spectrum_fx[0][n] = inv_spectrum_fx[ch1][n]; @@ -1692,11 +1683,115 @@ void mctStereoIGF_enc_fx( if ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] != hMCT->hBlockData[b]->hStereoMdct->IGFStereoMode[n] || hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS ) { + +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + Word16 p_orig_spectrum_e[2]; + IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; + hIGFEnc[0] = p_st[0]->hIGFEnc; + hIGFEnc[1] = p_st[1]->hIGFEnc; + + Word16 igfGridIdx; + IF( p_st[0]->last_core == ACELP_CORE && EQ_16( p_st[0]->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_TRAN; + } + ELSE IF( EQ_16( p_st[0]->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_NORM; + } + ELSE + { + /* It is short block */ + igfGridIdx = IGF_GRID_LB_SHORT; + } + f2me_buf( p_orig_spectrum[0][n], p_orig_spectrum_fx[0][n], &p_orig_spectrum_e[0], hIGFEnc[0]->infoStopLine ); + f2me_buf( p_orig_spectrum[1][n], p_orig_spectrum_fx[1][n], &p_orig_spectrum_e[1], hIGFEnc[1]->infoStopLine ); + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 *swb_offset; + hPrivateData = &hIGFEnc[ch]->igfData; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; + swb_offset = hGrid->swb_offset; + hIGFEnc[ch]->tns_predictionGain = float_to_fix16( hIGFEnc[ch]->tns_predictionGain_flt, Q23 ); + p_st[ch]->hTcxEnc->spectrum_e[n] = 31 - Q_factor_arrL( p_st[ch]->hTcxEnc->spectrum[n], hGrid->infoGranuleLen ); + p_st[ch]->hTcxEnc->spectrum_e[n] = s_max( p_st[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( &p_powerSpec[ch][0], hGrid->infoGranuleLen ) ); + p_st[ch]->hTcxEnc->spectrum_e[n] = s_max( p_st[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( inv_spectrum[ch][n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); + p_st[ch]->hTcxEnc->spectrum_e[n] = s_max( p_st[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( p_powerSpecMsInv[ch][0], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); + floatToFixed_arr32( p_st[ch]->hTcxEnc->spectrum[n], p_st[ch]->hTcxEnc->spectrum_fx[n], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], hGrid->infoGranuleLen ); + floatToFixed_arr32( &p_powerSpec[ch][0], &p_powerSpec_fx[ch][0], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], hGrid->infoGranuleLen ); + floatToFixed_arr32( inv_spectrum[ch][n], inv_spectrum_fx[ch][n], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); + floatToFixed_arr32( p_powerSpecMsInv[ch][0], p_powerSpecMsInv_fx[ch][0], 31 - p_st[ch]->hTcxEnc->spectrum_e[n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); + float max_sb = 0; + float max_tb = 0; + Word16 max_sb_fx = 0; + Word16 max_tb_fx = 0; + FOR( Word16 sfb = 0; sfb < 23; sfb++ ) + { + f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); + max_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_tb ); + max_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_tb ); + max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); + max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); + max_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_sb ); + max_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_sb ); + f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); + f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + } + FOR( int i = 0; i < IGF_MAX_TILES; i++ ) + { + hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ + hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ + FOR( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) + { + hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); + } + } + floatToFixed_arr16( &hGrid->whiteningThreshold_flt[0][0], &hGrid->whiteningThreshold[0][0], Q13, 2 * IGF_MAX_TILES ); + } +#endif /**********************************flt to fix ends here*******************************************************/ + hIGFEnc[0]->spec_be_igf_e = p_orig_spectrum_e[0]; + hIGFEnc[1]->spec_be_igf_e = p_orig_spectrum_e[1]; ProcessStereoIGF_fx( hMCT->hBlockData[b]->hStereoMdct, p_st, hMCT->hBlockData[b]->mask, -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING p_orig_spectrum_fx, -#endif - p_powerSpec_fx, p_powerSpecMsInv_fx, p_inv_spectrum_fx, p_orig_spectrum, p_powerSpec, p_powerSpecMsInv, p_inv_spectrum, n, sp_aud_decision0[ch1], p_st[0]->total_brate ); + p_powerSpec_fx, p_powerSpecMsInv_fx, p_inv_spectrum_fx, n, sp_aud_decision0[ch1], p_st[0]->total_brate ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + hPrivateData = &hIGFEnc[ch]->igfData; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; + me2f_buf( p_st[ch]->hTcxEnc->spectrum_fx[n], p_st[ch]->hTcxEnc->spectrum_e[n], p_st[ch]->hTcxEnc->spectrum[n], hGrid->infoGranuleLen ); + me2f_buf( &p_powerSpec_fx[ch][0], p_st[ch]->hTcxEnc->spectrum_e[n], &p_powerSpec[ch][0], hGrid->infoGranuleLen ); + for ( Word16 sfb = 0; sfb < 23; sfb++ ) + { + hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); + } + for ( int i = 0; i < IGF_MAX_TILES; i++ ) + { + hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ + hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ + for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) + { + hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); + } + } + } +#endif /**********************************fix to flt ends here*******************************************************/ } else { @@ -1834,8 +1929,7 @@ void mctStereoIGF_enc( { st = sts[ch]; - if ( - st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) + if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE ) { continue; } diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index c06dc405a87a1fb842a4041ee9569b00051449df..a07346292978d5fb5a3cb6f314305da3b13c1e6d 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -176,13 +176,31 @@ const int16_t itd_vad_band_tbl[STEREO_DFT_ITD_VAD_BAND_NUM+1] = 69, 80, 93, 107, 126, 147, 176, 211, 254, 320 }; -const int16_t ild_q[16] = +#ifdef IVAS_FLOAT_FIXED +const Word32 ild_q_Q25[16] = +{ + 0, 67108864, 134217728, 201326592, 268435456, 335544320, 436207616, 536870912, 637534208, 738197504, 838860800, 1006632960, 1174405120, 1342177280, 1509949440, 1677721600 +}; +#endif +const int16_t ild_q[16] = { 0,2,4,6,8,10,13,16,19,22,25,30,35,40,45,50 }; /* table of values of the analysis window cross-correlation function at 32kHz (stride 8) */ -const float Wn_table[50] = +#ifdef IVAS_FLOAT_FIXED +const Word32 Wn_table_fx[50] = /*Q31*/ +{ + 2147483647, 2145959424, 2142122880, 2136402432, 2129028864, 2120167040, 2109947136, 2098477824, + 2085854080, 2072159616, 2057470976, 2041858176, 2025387008, 2008118400, 1990110464, 1971418112, + 1952093824, 1932187008, 1911746048, 1890816640, 1869442688, 1847666560, 1825528448, 1803067264, + 1780320256, 1757322368, 1734107392, 1710707584, 1687152512, 1663470848, 1639688320, 1615829376, + 1591915648, 1567966080, 1543996928, 1520020480, 1496043392, 1472066048, 1448088832, 1424111488, + 1400134400, 1376157184, 1352179840, 1328202752, 1304225408, 1280248192, 1256271104, 1232293760, + 1208316416, 1184339328 +}; +#else +const float Wn_table[50] = { 1.0000000f, 0.9992902f, 0.9975037f, 0.9948399f, 0.9914063f, 0.9872797f, 0.9825207f, 0.9771799f, 0.9713015f, 0.9649245f, 0.9580846f, 0.9508143f, 0.9431443f, 0.9351030f, 0.9267174f, 0.9180131f, @@ -192,6 +210,7 @@ const float Wn_table[50] = 0.6519884f, 0.6408231f, 0.6296578f, 0.6184926f, 0.6073273f, 0.5961620f, 0.5849968f, 0.5738315f, 0.5626662f, 0.5515010f }; +#endif const float win_ana_8k[STEREO_DFT_OVL_8k] = { diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 89cdee23f6bc3495404e026dd4b163e2672dba12..d7479f70a735fcee5d9b992776b1006891281de0 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -80,9 +80,15 @@ extern const float icbwe_regressionValuesDFT[]; *----------------------------------------------------------------------------------*/ extern const int16_t itd_vad_band_tbl[]; +#ifdef IVAS_FLOAT_FIXED +extern const Word32 ild_q_Q25[16]; +#endif extern const int16_t ild_q[]; - +#ifdef IVAS_FLOAT_FIXED +extern const Word32 Wn_table_fx[50]; +#else extern const float Wn_table[]; +#endif extern const float win_ana_8k[STEREO_DFT_OVL_8k]; extern const float win_ana_12k8[STEREO_DFT_OVL_12k8]; diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 0729c6cd884a558fc573e1f2453cd4f6b54bc0a6..5ae9a546e4a8a6dacbf42c2b8a4f4c5822a9b60d 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -230,6 +230,7 @@ typedef struct stereo_dft_enc_data_struct /* Stereo CNG */ float sidSideGain[STEREO_DFT_ERB4_BANDS]; + Word32 sidSideGain_fx[STEREO_DFT_ERB4_BANDS]; // Q31? float win_ana_energy; Word16 win_ana_energy_fx; // Q15 float xspec_smooth[STEREO_DFT_N_32k_ENC]; @@ -264,7 +265,7 @@ typedef struct stereo_dft_enc_data_struct ITD_DATA_HANDLE hItd; float voicing_lt; - Word32 voicing_lt_fx; + Word32 voicing_lt_fx; // Q31 int16_t currentNumUpdates; @@ -323,33 +324,40 @@ typedef struct stereo_dft_enc_data_struct Word16 lbEner_fx_e; #endif int16_t flip_sign; - Word32 dmx_res_all_prev_fx; /* energy of the previous frame Q31*/ - Word16 switch_fade_factor_fx; /* Adaptive fade factor for switch frame Q15*/ - Word32 res_dmx_ratio_lt_fx; /* long term energy ratio between RES and DMX Q31*/ - Word32 pre_sub_nrg_DMX_fx[STEREO_DFT_BAND_MAX]; - Word32 diff_l_h_sm_fx; - Word32 diff_r_h_sm_fx; - Word32 prev_fac2_fx; // initilizae in Q31 - Word32 res_pred_gain_f_fx[STEREO_DFT_BAND_MAX]; + Word32 dmx_res_all_prev_fx; /* energy of the previous frame Q31*/ + Word16 switch_fade_factor_fx; /* Adaptive fade factor for switch frame Q15*/ + Word32 res_dmx_ratio_lt_fx; /* long term energy ratio between RES and DMX Q31*/ + Word32 pre_sub_nrg_DMX_fx[STEREO_DFT_BAND_MAX]; // Q(31 - pre_sub_nrg_DMX_fx_e[]) + Word16 pre_sub_nrg_DMX_fx_e[STEREO_DFT_BAND_MAX]; + Word32 diff_l_h_sm_fx; // Q(31 - diff_l_h_sm_fx_e) + Word16 diff_l_h_sm_fx_e; + Word32 diff_r_h_sm_fx; // Q(31 - diff_r_h_sm_fx_e) + Word16 diff_r_h_sm_fx_e; + Word32 prev_fac2_fx; // Q31 + Word32 res_pred_gain_f_fx[STEREO_DFT_BAND_MAX]; // Q31 Word32 nrg_L_fx[2]; Word32 nrg_R_fx[2]; Word32 nrg_DMX_fx[2]; Word32 res_pred_gain_fx[STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX]; /*prediction gain for the residual HFs */ /* Q31 */ - Word32 gainIPD_sm_fx; /* long-term gain IPD for NIPD detection */ ////initilizae in Q31 + Word32 gainIPD_sm_fx; /* long-term gain IPD for NIPD detection */ // Q31 Word32 sfm_fx; // Q31 - Word32 sum_dot_prod_real_fx; - Word32 sum_dot_prod_img_fx; - Word32 dot_prod_real_smooth_fx[STEREO_DFT_BAND_MAX]; - Word32 dot_prod_img_smooth_fx[STEREO_DFT_BAND_MAX]; - Word32 ipd_buf_fx[STEREO_DFT_BAND_MAX][STEREO_DFT_IPD_BUF_LEN]; - Word32 prev_gipd_fx; - Word32 xspec_smooth_fx[STEREO_DFT_N_32k_ENC]; + Word32 sum_dot_prod_real_fx; // Q(31 - sum_dot_prod_real_fx_e) + Word16 sum_dot_prod_real_fx_e; + Word32 sum_dot_prod_img_fx; // Q(31 - sum_dot_prod_img_fx_e) + Word16 sum_dot_prod_img_fx_e; + Word32 dot_prod_real_smooth_fx[STEREO_DFT_BAND_MAX]; // Q(31 - dot_prod_real_smooth_fx_e[]) + Word16 dot_prod_real_smooth_fx_e[STEREO_DFT_BAND_MAX]; + Word32 dot_prod_img_smooth_fx[STEREO_DFT_BAND_MAX]; // Q(31 - dot_prod_img_smooth_fx_e[]) + Word16 dot_prod_img_smooth_fx_e[STEREO_DFT_BAND_MAX]; + Word32 ipd_buf_fx[STEREO_DFT_BAND_MAX][STEREO_DFT_IPD_BUF_LEN]; // Q13 + Word32 prev_gipd_fx; // Q13 + Word32 xspec_smooth_fx[STEREO_DFT_N_32k_ENC]; // Q(31 - xspec_smooth_fx_e) Word16 xspec_smooth_fx_e; - Word32 Spd_L_smooth_fx[STEREO_DFT_N_32k_ENC / 2]; + Word32 Spd_L_smooth_fx[STEREO_DFT_N_32k_ENC / 2]; // Q(31 - Spd_L_smooth_fx_e) Word16 Spd_L_smooth_fx_e; - Word32 Spd_R_smooth_fx[STEREO_DFT_N_32k_ENC / 2]; + Word32 Spd_R_smooth_fx[STEREO_DFT_N_32k_ENC / 2]; // Q(31 - Spd_R_smooth_fx_e) Word16 Spd_R_smooth_fx_e; - Word32 sid_gipd_fx; + Word32 sid_gipd_fx; // Q13 const Word32 *win_fx; /* DFT window */ const Word32 *win_8k_fx; /* DFT window */ const Word32 *win_12k8_fx; /* DFT window */ @@ -376,10 +384,14 @@ typedef struct stereo_dft_enc_data_struct Word32 res_cod_NRG_S_fx[STEREO_DFT_BAND_MAX]; Word32 res_cod_SNR_M_fx[STEREO_DFT_BAND_MAX]; Word32 old_snr_fx; - Word32 past_nrgL_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; - Word32 past_nrgR_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; - Word32 past_dot_prod_real_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; - Word32 past_dot_prod_imag_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word32 past_nrgL_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; // Q(31 - past_nrgL_fx_e[]) + Word16 past_nrgL_fx_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word32 past_nrgR_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; // Q(31 - past_nrgR_fx_e[]) + Word16 past_nrgR_fx_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word32 past_dot_prod_real_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; // Q(31 - past_dot_prod_real_fx_e[]) + Word16 past_dot_prod_real_fx_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word32 past_dot_prod_imag_fx[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; // Q(31 - past_dot_prod_imag_fx_e[]) + Word16 past_dot_prod_imag_fx_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; Word32 output_mem_dmx_fx[STEREO_DFT_OVL_MAX]; // Q16 Word32 output_mem_dmx_12k8_fx[STEREO_DFT_OVL_12k8]; // Q16 Word32 output_mem_dmx_16k_fx[STEREO_DFT_OVL_16k]; /*can hold 16, 12.8 or 32kHz signals*/ // Q16 diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 08bb661e0f6bd862a9c1680ac516bbf6cdc4405a..2dddb2bd16477543bf0a068180d90137319d62e8 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -68,19 +68,70 @@ static void stereo_dft_enc_open( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, const in static void stereo_dft_enc_open_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, const Word32 input_Fs, const Word16 max_bwidth ); #endif // IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_enc_compute_prm_fx( + STEREO_DFT_ENC_DATA_HANDLE hStereoDft, + Word32 *DFT_L_fx, // Q(31-DFT_L_fx_e[]) + Word16 *DFT_L_fx_e, + Word32 *DFT_R_fx, // Q(31-DFT_R_fx_e[]) + Word16 *DFT_R_fx_e, + Word16 k_offset, + Word16 flag_quant, + const Word16 sp_aud_decision0, + const Word16 vad_flag, + Word32 *bin_nrgL_fx, // Q(31-bin_nrgL_fx_e[]) + Word16 *bin_nrgL_fx_e, + Word32 *bin_nrgR_fx, // Q(31-bin_nrgR_fx_e[]) + Word16 *bin_nrgR_fx_e, + Word32 *dot_prod_nrg_ratio_fx, // Q(31-dot_prod_nrg_ratio_fx_e[]) + Word16 *dot_prod_nrg_ratio_fx_e ); +#else static void stereo_dft_enc_compute_prm( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, float *DFT_L, float *DFT_R, int16_t k_offset, int16_t flag_quant, const int16_t sp_aud_decision0, const int16_t vad_flag, float *bin_nrgL, float *bin_nrgR, float *dot_prod_nrg_ratio ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word32 stereo_dft_calc_mean_bipd_fx( Word32 *pIpd, Word32 ipd_buf[STEREO_DFT_IPD_BUF_LEN] ); +#else static float stereo_dft_calc_mean_bipd( float *pIpd, float ipd_buf[STEREO_DFT_IPD_BUF_LEN] ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word32 stereo_dft_calc_mean_ipd_change_fx( + Word32 *pIpd, /* i : bandwise IPDs Q13 */ + Word32 *ipd_smooth, /* i : mean of previous bandwise IPDs Q13 */ + Word16 gipd_band_max /* i : number of IPD bands */ +); +#else static float stereo_dft_calc_mean_ipd_change( float *pIpd, float *ipd_smooth, int16_t gipd_band_max ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_gipd_stabilization_fx( + Word32 *pgIpd, /* i/o: global IPD to be stabilized Q13 */ + Word32 prev_gipd, /* i : previous global IPD Q13 */ + Word32 ipd_mean_change /* i : mean of previous bandwise IPDs Q13 */ +); +#else static void stereo_dft_gipd_stabilization( float *pgIpd, float prev_gipd, float ipd_mean_change ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_enc_get_nipd_flag_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, const Word16 sp_aud_decision0, const Word32 gainIPD ); +#else static void stereo_dft_enc_get_nipd_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, const int16_t sp_aud_decision0, const float gainIPD ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_enc_get_reverb_flag_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, Word32 *pPredGain, Word32 *sub_nrg_DMX, Word16 *sub_nrg_DMX_e, const Word32 *sub_nrg_L, const Word16 *sub_nrg_L_e, const Word32 *sub_nrg_R, const Word16 *sub_nrg_R_e, const Word16 k_offset, const Word32 *bin_nrgL, const Word16 *bin_nrgL_e, const Word32 *bin_nrgR, const Word16 *bin_nrgR_e ); +#else static void stereo_dft_enc_get_reverb_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, float *pPredGain, float *sub_nrg_DMX, const float *sub_nrg_L, const float *sub_nrg_R, const int16_t k_offset, const float *bin_nrgL, const float *bin_nrgR ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word32 stereo_dft_gain_offset_fx( const Word32 c, const Word16 c_e, const Word16 itd ); +#else static float stereo_dft_gain_offset( const float c, const int16_t itd ); +#endif static void side_gain_mode_decision( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, int16_t encoded_ind_GR[], const int16_t sp_aud_decision0, const int32_t last_core_brate ); @@ -96,7 +147,154 @@ static void stereo_dft_enc_get_res_cod_mode_flag( STEREO_DFT_ENC_DATA_HANDLE hSt * * Joint quantization routine for residual gains *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void stereo_dft_quantize_res_gains_fx( + const Word32 *g, // Q31 + const Word32 *r, // Q31 + Word32 *gq, // Q31 + Word32 *rq, // Q31 + Word16 *ig, + Word16 *ir ) +{ + Word8 sign; + Word16 min_ind, i; + Word32 min_val, old_val, gg, rr; + Word16 level, index; + Word32 ild; // Q25 + Word32 L_tmp; + Word16 L_tmp_e; + + gg = *g; + move32(); + + IF( rq != NULL ) + { + rr = *r; + move32(); + } + ELSE + { + rr = 0; + move32(); + } + + IF( gg < 0 ) + { + gg = L_negate( gg ); + sign = -1; + move16(); + } + ELSE + { + sign = 1; + move16(); + } + + + // gg = min(gg, 1 - EPSILON); + // rr = min(rr, sqrtf(1 - gg * gg) - EPSILON); + L_tmp = L_sub( MAX_32, Mpy_32_32( gg, gg ) ); + L_tmp_e = 0; + move16(); + L_tmp = Sqrt32( L_tmp, &L_tmp_e ); + L_tmp = L_shl( L_tmp, L_tmp_e ); // Q31 + rr = L_min( rr, L_tmp ); + + /* we calculate the ILD ... */ + // ild = 10.f * log10f(((1 + gg) * (1 + gg) + rr * rr) / ((1 - gg) * (1 - gg) + rr * rr)); + ild = L_add( Mpy_32_32( L_add( ONE_IN_Q30, L_shr( gg, 1 ) ), L_add( ONE_IN_Q30, L_shr( gg, 1 ) ) ), L_shr_r( Mpy_32_32( rr, rr ), 2 ) ); // Q29 + ild = BASOP_Util_Log10( ild, 2 ); // Q25 + L_tmp = L_add( L_shr( Mpy_32_32( L_sub( MAX_32, gg ), L_sub( MAX_32, gg ) ), 1 ), L_shr( Mpy_32_32( rr, rr ), 1 ) ); // Q30 + L_tmp = BASOP_Util_Log10( L_tmp, 1 ); // Q25 + ild = L_sub( ild, L_tmp ); + ild = W_extract_h( W_shl( W_mult0_32_32( 10, ild ), 32 ) ); + + /* ... which is truncated to the range [0,50] ... */ + // ild = ild > 50 ? 50 : ild; + ild = L_min( 1677721600 /*50*/, ild ); + + /* ... and determine the optimal ILD quantization ...*/ + min_ind = 0; + move16(); + // old_val = fabsf(ild_q[0] - ild); + old_val = L_abs( L_sub( ild_q_Q25[0], ild ) ); + + FOR( i = 1; i < 16; i++ ) + { + // min_val = fabsf(ild_q[i] - ild); + min_val = L_abs( L_sub( ild_q_Q25[i], ild ) ); + IF( LT_32( min_val, old_val ) ) + { + min_ind = i; + move16(); + } + ELSE + { + BREAK; + } + old_val = min_val; + move32(); + } + + /* ... which determines the quantization level: */ + level = min_ind; + move16(); + + /* Now we look for the closest quantization point in the corresponding column of res_gain_energy_q*/ + // old_val = FLT_MAX; + old_val = MAX_32; + move32(); + min_ind = 0; + move16(); + index = -1; + move16(); + FOR( i = 0; i < 8; i++ ) + { + // min_val = (gg - dft_res_gains_q[8 * level + i][0]) * (gg - dft_res_gains_q[8 * level + i][0]) + (rr - dft_res_gains_q[8 * level + i][1]) * (rr - dft_res_gains_q[8 * level + i][1]); + min_val = L_add_sat( Mpy_32_32( L_sub( gg, dft_res_gains_q_fx[8 * level + i][0] ), L_sub( gg, dft_res_gains_q_fx[8 * level + i][0] ) ), Mpy_32_32( L_sub( rr, dft_res_gains_q_fx[8 * level + i][1] ), L_sub( rr, dft_res_gains_q_fx[8 * level + i][1] ) ) ); // saturation is expected + + // min_ind = min_val < old_val ? i : min_ind; + // old_val = min_val < old_val ? min_val : old_val; + IF( LT_32( min_val, old_val ) ) + { + min_ind = i; + move16(); + old_val = min_val; + move32(); + } + + index = min_ind; + move16(); + } + + /* and here we are: */ + IF( rq != NULL ) + { + //*gq = dft_res_gains_q[8 * level + index][0] * sign; + *gq = W_extract_l( W_mult0_32_32( dft_res_gains_q_fx[8 * level + index][0], sign ) ); + move32(); + //*rq = dft_res_gains_q[8 * level + index][1]; + *rq = dft_res_gains_q_fx[8 * level + index][1]; + move32(); + + *ir = index; + move16(); + } + //*ig = sign < 0 ? 15 - level : 15 + level; + IF( sign < 0 ) + { + *ig = sub( 15, level ); + move16(); + } + ELSE + { + *ig = add( 15, level ); + move16(); + } + return; +} +#endif void stereo_dft_quantize_res_gains( const float *g, const float *r, @@ -195,7 +393,69 @@ void stereo_dft_quantize_res_gains( * * Quantize the IPD between [-PI, PI] on 3 or 4 bits *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_quantize_ipd_fx( + const Word32 *in, // Q13 + Word32 *out, // Q13 + Word16 *ind, + const Word16 bits ) +{ + Word16 max_ind; + Word32 delta; + Word16 tmp, tmp_e; + + IF( EQ_16( bits, 2 ) ) /* New 2-bit phase quantization for the highest frequency band only */ + { + delta = EVS_PI_FX / 2; + move16(); + max_ind = 3; + move16(); + } + ELSE IF( EQ_16( bits, 3 ) ) + { + delta = EVS_PI_FX / 4; + move16(); + max_ind = 7; + move16(); + } + ELSE IF( EQ_16( bits, 4 ) ) + { + delta = EVS_PI_FX / 8; + move16(); + max_ind = 15; + move16(); + } + ELSE + { + delta = EVS_PI_FX / 4; + move16(); + max_ind = 7; + move16(); + assert( 0 ); + } + + //*ind = (int16_t)(((*in + EVS_PI) / delta) + 0.5f); + tmp = BASOP_Util_Divide3232_Scale( L_add( *in, EVS_PI_FX ), delta, &tmp_e ); + *ind = shr_r( tmp, sub( 15, tmp_e ) ); // Q0 + move16(); + + /*modulo 2*PI*/ + if ( EQ_16( *ind, add( max_ind, 1 ) ) ) + { + *ind = 0; + move16(); + } + /*Sanity check since no saturation can normally happen*/ + *ind = s_min( s_max( *ind, 0 ), max_ind ); + move16(); + + *out = L_sub( L_mult0( *ind, extract_l( delta ) ), EVS_PI_FX ); // Q13 + move32(); + + return; +} +#endif static void stereo_dft_quantize_ipd( const float *in, float *out, @@ -243,7 +503,6 @@ static void stereo_dft_quantize_ipd( return; } - /*------------------------------------------------------------------------- * stereo_dft_enc_create() * @@ -531,6 +790,9 @@ static void stereo_dft_enc_open( /* reset DFT stereo memories */ stereo_dft_enc_reset( hStereoDft ); +#ifdef IVAS_FLOAT_FIXED + stereo_dft_enc_reset_fx( hStereoDft ); +#endif return; } @@ -670,6 +932,12 @@ void stereo_dft_enc_reset( set_zero( hStereoDft->gipd, STEREO_DFT_ENC_DFT_NB ); set_zero( hStereoDft->dot_prod_real_smooth, STEREO_DFT_BAND_MAX ); set_zero( hStereoDft->dot_prod_img_smooth, STEREO_DFT_BAND_MAX ); +#ifdef IVAS_FLOAT_FIXED + set_zero_fx( hStereoDft->dot_prod_real_smooth_fx, STEREO_DFT_BAND_MAX ); + set16_zero_fx( hStereoDft->dot_prod_real_smooth_fx_e, STEREO_DFT_BAND_MAX ); + set_zero_fx( hStereoDft->dot_prod_img_smooth_fx, STEREO_DFT_BAND_MAX ); + set16_zero_fx( hStereoDft->dot_prod_img_smooth_fx_e, STEREO_DFT_BAND_MAX ); +#endif for ( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { set_zero( hStereoDft->ipd_buf[i], STEREO_DFT_IPD_BUF_LEN ); @@ -751,11 +1019,7 @@ void stereo_dft_enc_reset( hStereoDft->first_frm_flag = 1; - stereo_enc_itd_init( hStereoDft->hItd ); -#ifdef IVAS_FLOAT_FIXED - stereo_enc_itd_init_fx( hStereoDft->hItd ); -#endif return; } @@ -771,68 +1035,114 @@ void stereo_dft_enc_reset_fx( set16_fx( hStereoDft->side_gain_index_ECDiff, 0, STEREO_DFT_BAND_MAX ); set16_fx( hStereoDft->side_gain_index_ECprevious, 15, STEREO_DFT_BAND_MAX ); hStereoDft->side_gain_counter = 0; + move16(); hStereoDft->side_gain_bitdiff_lp_fx = STEREO_DFT_BITDIFF_INIT_FX; + move16(); set_zero_fx( hStereoDft->gipd_fx, STEREO_DFT_ENC_DFT_NB ); set_zero_fx( hStereoDft->dot_prod_real_smooth_fx, STEREO_DFT_BAND_MAX ); set_zero_fx( hStereoDft->dot_prod_img_smooth_fx, STEREO_DFT_BAND_MAX ); - for ( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) + FOR( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { set_zero_fx( hStereoDft->ipd_buf_fx[i], STEREO_DFT_IPD_BUF_LEN ); } hStereoDft->prev_gipd_fx = 0; + move32(); hStereoDft->gipd_index = 0; + move16(); set_zero_fx( hStereoDft->res_pred_gain_fx, i_mult( STEREO_DFT_ENC_DFT_NB, STEREO_DFT_BAND_MAX ) ); set16_fx( hStereoDft->res_pred_index_EC, 0, STEREO_DFT_BAND_MAX ); set16_fx( hStereoDft->res_pred_index_ECDiff, 0, STEREO_DFT_BAND_MAX ); set16_fx( hStereoDft->res_pred_index_ECprevious, 0, STEREO_DFT_BAND_MAX ); hStereoDft->res_pred_counter = 0; + move16(); set_zero_fx( hStereoDft->past_nrgL_fx, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); + set16_zero_fx( hStereoDft->past_nrgL_fx_e, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); set_zero_fx( hStereoDft->past_nrgR_fx, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); + set16_zero_fx( hStereoDft->past_nrgR_fx_e, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); set_zero_fx( hStereoDft->past_dot_prod_real_fx, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); + set16_zero_fx( hStereoDft->past_dot_prod_real_fx_e, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); set_zero_fx( hStereoDft->past_dot_prod_imag_fx, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); + set16_zero_fx( hStereoDft->past_dot_prod_imag_fx_e, i_mult( STEREO_DFT_NRG_PAST_LEN, STEREO_DFT_BAND_MAX ) ); + hStereoDft->nrg_past_pos = 0; + move16(); hStereoDft->res_dmx_ratio_lt_fx = MAX_32; + move32(); hStereoDft->hangover_cnt0 = 0; + move16(); hStereoDft->hangover_cnt1 = 0; + move16(); hStereoDft->dmx_res_all_prev_fx = 1; + move32(); hStereoDft->last_res_cod_mode_modify_flag = 0; + move16(); hStereoDft->res_cod_sw_flag = 0; + move16(); hStereoDft->switch_fade_factor_fx = ONE_IN_Q14; // Q15/2 + move16(); hStereoDft->res_cod_mode[STEREO_DFT_OFFSET - 1] = STEREO_DFT_RES_COD_1kHz; FOR( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { hStereoDft->res_cod_NRG_M_fx[i] = 0; + move32(); hStereoDft->res_cod_NRG_S_fx[i] = 0; + move32(); } hStereoDft->old_snr_fx = 0; + move32(); hStereoDft->reverb_flag = 0; + move16(); set_zero_fx( hStereoDft->pre_sub_nrg_DMX_fx, STEREO_DFT_BAND_MAX ); + set16_zero_fx( hStereoDft->pre_sub_nrg_DMX_fx_e, STEREO_DFT_BAND_MAX ); hStereoDft->diff_l_h_sm_fx = 0; + move32(); + hStereoDft->diff_l_h_sm_fx_e = 0; + move16(); hStereoDft->diff_r_h_sm_fx = 0; + move32(); + hStereoDft->diff_r_h_sm_fx_e = 0; + move16(); hStereoDft->prev_fac2_fx = MAX_32; + move32(); set_zero_fx( hStereoDft->res_pred_gain_f_fx, STEREO_DFT_BAND_MAX ); /*misc*/ hStereoDft->no_ipd_flag = 1; /* Initialization of the no IPD variables */ + move16(); hStereoDft->prev_no_ipd_flag = 1; + move16(); hStereoDft->no_ipd_cnt = 0; + move16(); hStereoDft->no_ipd_cnt1 = 0; + move16(); hStereoDft->attackPresent = 0; + move16(); hStereoDft->wasTransient = 0; + move16(); hStereoDft->gainIPD_sm_fx = MAX_32; + move32(); hStereoDft->voicing_lt_fx = 0; + move32(); hStereoDft->flip_sign = 1; + move16(); hStereoDft->sfm_fx = 0; + move32(); hStereoDft->sum_dot_prod_real_fx = 0; + move32(); + hStereoDft->sum_dot_prod_real_fx_e = 0; + move16(); hStereoDft->sum_dot_prod_img_fx = 0; + move32(); + hStereoDft->sum_dot_prod_img_fx_e = 0; + move16(); /*Coherence*/ set32_fx( hStereoDft->xspec_smooth_fx, MAX_32, STEREO_DFT_N_32k_ENC ); @@ -840,21 +1150,33 @@ void stereo_dft_enc_reset_fx( set32_fx( hStereoDft->Spd_R_smooth_fx, MAX_32, shr( STEREO_DFT_N_32k_ENC, 1 ) ); hStereoDft->currentNumUpdates = 0; + move16(); hStereoDft->expectedNumUpdates = FIXED_SID_RATE; + move16(); hStereoDft->resetFrames = 0; + move16(); hStereoDft->sid_gipd_fx = 0; + move32(); hStereoDft->prev_sid_gipd_fx = 0; + move32(); hStereoDft->prev_sid_no_ipd_flag = 1; + move16(); hStereoDft->coh_fade_counter = 0; + move16(); /* Xtalk classifier */ hStereoDft->hItd->prev_m1_fx = 0; + move32(); hStereoDft->hItd->prev_m2_fx = 0; + move32(); hStereoDft->hItd->prev_itd1 = 0; + move16(); hStereoDft->hItd->prev_itd2 = 0; + move16(); hStereoDft->first_frm_flag = 1; + move16(); stereo_enc_itd_init_fx( hStereoDft->hItd ); @@ -1049,6 +1371,7 @@ void stereo_dft_enc_update_fx( tmp = BASOP_Util_Divide3232_Scale_cadence( tmp, hStereoDft->N, &exp ); hStereoDft->res_cod_line_max = extract_l( L_shr( tmp, sub( 31, exp ) ) ); move16(); + // hStereoDft->res_cod_line_max = 8 * (hStereoDft->res_cod_line_max / 8); hStereoDft->res_cod_line_max = shl( shr( hStereoDft->res_cod_line_max, 3 ), 3 ); move16(); hStereoDft->res_pred_band_min = s_max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); @@ -2200,38 +2523,60 @@ float stereo_dft_enc_synthesize( * 2) Mid/Side computation *-------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -#if 0 // def IVAS_FLOAT_FIXED void stereo_dft_enc_process( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const Word16 vad_flag_dtx[], /* i : VAD dtx flags */ - const Word16 vad_hover_flag[], /* i : VAD hangover flags */ - const Word16 input_frame /* i : input frame length */ + const int16_t vad_flag_dtx[], /* i : VAD dtx flags */ + const int16_t vad_hover_flag[], /* i : VAD hangover flags */ + const int16_t input_frame /* i : input frame length */ ) { - Word16 i, j, b; - Word32 *pDFT_L, *pDFT_R; - Word32 *pDFT_DMX; - Word32 *pDFT_RES; - Word16 k_offset; - Word32 *pgIpd; - Word32 *pSideGain; - Word32 c, alpha, g; - Word32 wL, wR, wS; - Word32 tmp; - Word32 s, c1, s1; - Word32 fac_att; + int16_t i, j, b; + float *pDFT_L, *pDFT_R; +#ifdef IVAS_FLOAT_FIXED + Word32 *pDFT_L_fx, *pDFT_R_fx; +#endif + float *pDFT_DMX; + float *pDFT_RES; + int16_t k_offset; + float *pgIpd; + float *pSideGain; + float c /*, alpha*/, g; + Word16 c_fx, alpha_fx /*Q13*/ /*, g_fx*/; + float wL, wR, wS; + float tmp; + Word16 tmp_fx; + Word32 tmp_32fx; + float s /*, c1, s1*/; + Word16 s_fx, c1_fx, s1_fx; + float fac_att; + Word16 fac_att_fx; STEREO_DFT_ENC_DATA_HANDLE hStereoDft; - Word32 DFT_DMX[STEREO_DFT_N_MAX_ENC]; - Word32 DFT_RES[STEREO_DFT_N_8k_ENC]; - Word32 input_Fs; - Word32 bin_nrgL[STEREO_DFT_N_MAX_ENC]; - Word32 bin_nrgR[STEREO_DFT_N_MAX_ENC]; - Word32 *pNrgL, *pNrgR; - Word32 res_nrg_all_curr, dmx_nrg_all_curr; - Word32 res_dmx_ratio, frame_nrg_ratio; - Word32 dot_prod_nrg_ratio[STEREO_DFT_BAND_MAX]; /* contains only dot product for higher bands */ - Word32 sum_nrg_L2, sum_nrg_R2, dot_prod_real2; - Word32 sum_nrg_Mid, sum_abs; + float DFT_DMX[STEREO_DFT_N_MAX_ENC]; + float DFT_RES[STEREO_DFT_N_8k_ENC]; + int32_t input_Fs; + float bin_nrgL[STEREO_DFT_N_MAX_ENC]; +#ifdef IVAS_FLOAT_FIXED + Word32 bin_nrgL_fx[STEREO_DFT_N_MAX_ENC]; + Word16 bin_nrgL_fx_e[STEREO_DFT_N_MAX_ENC]; +#endif + float bin_nrgR[STEREO_DFT_N_MAX_ENC]; +#ifdef IVAS_FLOAT_FIXED + Word32 bin_nrgR_fx[STEREO_DFT_N_MAX_ENC]; + Word16 bin_nrgR_fx_e[STEREO_DFT_N_MAX_ENC]; +#endif + float *pNrgL, *pNrgR; + float res_nrg_all_curr, dmx_nrg_all_curr; + float res_dmx_ratio, frame_nrg_ratio; + Word32 dot_prod_nrg_ratio_fx[STEREO_DFT_BAND_MAX]; /* contains only dot product for higher bands Q31 */ + Word16 dot_prod_nrg_ratio_fx_e[STEREO_DFT_BAND_MAX]; /* contains only dot product for higher bands Q31 */ + float dot_prod_nrg_ratio[STEREO_DFT_BAND_MAX]; /* contains only dot product for higher bands */ + float sum_nrg_L2, sum_nrg_R2, dot_prod_real2; + float sum_nrg_Mid, sum_abs; + Word16 tmp_e; + /*Word64 W_tmp; + Word16 W_shift;*/ + Word32 DFT_L_tmp[STEREO_DFT_N_MAX_ENC], DFT_R_tmp[STEREO_DFT_N_MAX_ENC]; + Word16 DFT_L_e_tmp[STEREO_DFT_N_MAX_ENC], DFT_R_e_tmp[STEREO_DFT_N_MAX_ENC]; /*------------------------------------------------------------------* * Initialization @@ -2249,13 +2594,11 @@ void stereo_dft_enc_process( hStereoDft->gipd_band_max = dft_band_ipd[1][3]; hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->band_res[k_offset]][hStereoDft->res_cod_mode[k_offset]]; - //hStereoDft->res_cod_line_max = (int16_t) ( 0.5f + ( hStereoDft->band_limits[hStereoDft->res_cod_band_max] - 1 ) * 2.f * input_frame / (float) ( hStereoDft->NFFT ) ); - Word32 tmp = L_shl(L_mult0(sub(hStereoDft->band_limits[hStereoDft->res_cod_band_max], 1), hStereoDft->N), 1); - Word16 exp; - tmp = BASOP_Util_Divide1616_Scale(tmp, hStereoDft->N, &exp); - hStereoDft->res_cod_line_max = extract_l(L_shr(tmp, sub(31, exp))); - hStereoDft->res_cod_line_max = shl(shr(hStereoDft->res_cod_line_max, 3), 3); - + // hStereoDft->res_cod_line_max = (int16_t) ( 0.5f + ( hStereoDft->band_limits[hStereoDft->res_cod_band_max] - 1 ) * 2.f * input_frame / (float) ( hStereoDft->NFFT ) ); + tmp_32fx = L_shl( L_mult0( sub( hStereoDft->band_limits[hStereoDft->res_cod_band_max], 1 ), input_frame ), 1 ); + tmp_32fx = BASOP_Util_Divide3216_Scale( tmp_32fx, hStereoDft->NFFT, &tmp_e ); + hStereoDft->res_cod_line_max = extract_l( L_shr_r( tmp_32fx, sub( 31, tmp_e ) ) ); + hStereoDft->res_cod_line_max = shl( shr( hStereoDft->res_cod_line_max, 3 ), 3 ); hStereoDft->res_pred_band_min = s_max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); @@ -2264,77 +2607,231 @@ void stereo_dft_enc_process( hStereoDft->voicing_lt_fx = L_add( Mpy_32_16_1( hStereoDft->voicing_lt_fx, 24576 ), L_mult( 8192, hCPE->hCoreCoder[0]->voicing_fx[0] ) ); hStereoDft->voicing_lt_fx = L_add( Mpy_32_16_1( hStereoDft->voicing_lt_fx, 24576 ), L_mult( 8192, hCPE->hCoreCoder[0]->voicing_fx[1] ) ); + /*------------------------------------------------------------------* * Compute stereo parameters *-----------------------------------------------------------------*/ /*ITD in Frequency domain*/ - fac_att = MAX_32; - - pDFT_L = hStereoDft->DFT_fx[0]; - pDFT_R = hStereoDft->DFT_fx[1]; + fac_att = 1.0f; + fac_att_fx = MAX_16; + move16(); + pDFT_L = hStereoDft->DFT[0]; + pDFT_R = hStereoDft->DFT[1]; +#ifdef IVAS_FLOAT_FIXED + pDFT_L_fx = DFT_L_tmp; + pDFT_R_fx = DFT_R_tmp; +#ifdef MSAN_FIX + FOR( i = 0; i < hStereoDft->NFFT; i++ ) +#else + FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) +#endif // MSAN_FIX + { + tmp_e = norm_l( hStereoDft->DFT_fx[0][i] ); + pDFT_L_fx[i] = L_shl( hStereoDft->DFT_fx[0][i], tmp_e ); + move32(); + DFT_L_e_tmp[i] = sub( hStereoDft->DFT_fx_e[0], tmp_e ); + move16(); + tmp_e = norm_l( hStereoDft->DFT_fx[1][i] ); + pDFT_R_fx[i] = L_shl( hStereoDft->DFT_fx[1][i], tmp_e ); + move32(); + DFT_R_e_tmp[i] = sub( hStereoDft->DFT_fx_e[1], tmp_e ); + move16(); + } +#endif { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /*flt2fix*/ + hStereoDft->sfm_fx = floatToFixed( hStereoDft->sfm, 31 ); + f2me_buf( hStereoDft->xspec_smooth, hStereoDft->xspec_smooth_fx, &hStereoDft->xspec_smooth_fx_e, STEREO_DFT_N_32k_ENC ); + f2me_buf( hStereoDft->Spd_L_smooth, hStereoDft->Spd_L_smooth_fx, &hStereoDft->Spd_L_smooth_fx_e, STEREO_DFT_N_32k_ENC / 2 ); + f2me_buf( hStereoDft->Spd_R_smooth, hStereoDft->Spd_R_smooth_fx, &hStereoDft->Spd_R_smooth_fx_e, STEREO_DFT_N_32k_ENC / 2 ); + floatToFixed_arrL( hStereoDft->hItd->itd, hStereoDft->hItd->itd_fx, 16, STEREO_DFT_ENC_DFT_NB ); + floatToFixed_arrL( hStereoDft->hItd->deltaItd, hStereoDft->hItd->deltaItd_fx, 16, STEREO_DFT_ENC_DFT_NB ); + floatToFixed_arrL( hCPE->hStereoClassif->xtalk_fv, hCPE->hStereoClassif->xtalk_fv_fx, 15, SSC_MAX_NFEA ); + floatToFixed_arrL( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, 15, SSC_MAX_NFEA ); + f2me( hCPE->hStereoClassif->ave_ener_L, &hCPE->hStereoClassif->ave_ener_L_fx, &hCPE->hStereoClassif->ave_ener_L_fx_e ); + f2me( hCPE->hStereoClassif->ave_ener_R, &hCPE->hStereoClassif->ave_ener_R_fx, &hCPE->hStereoClassif->ave_ener_R_fx_e ); + hStereoDft->hItd->prev_m1_fx = floatToFixed( hStereoDft->hItd->prev_m1, 31 ); + hStereoDft->hItd->prev_m2_fx = floatToFixed( hStereoDft->hItd->prev_m2, 31 ); + f2me( hStereoDft->hItd->currFlatness, &hStereoDft->hItd->currFlatness_fx, &hStereoDft->hItd->currFlatness_fx_e ); +#ifdef MSAN_FIX + hCPE->hStereoClassif->prev_IPD_fx = floatToFixed( hCPE->hStereoClassif->prev_IPD, Q29 ); + hCPE->hStereoClassif->prev_g_IPD_fx = floatToFixed( hCPE->hStereoClassif->prev_g_IPD, Q29 ); + hCPE->hStereoClassif->prev_ratio_m1_m2_fx = floatToFixed( hCPE->hStereoClassif->prev_ratio_m1_m2, Q31 ); +#endif + +#ifndef MSAN_FIX + hCPE->hStereoClassif->xtalk_score_fx = floatToFixed( hCPE->hStereoClassif->xtalk_score, 31 ); +#endif // !MSAN_FIX + floatToFixed_arrL( hCPE->hStereoClassif->xtalk_score_buf, hCPE->hStereoClassif->xtalk_score_buf_fx, 31, XTALK_SCORE_BUF_LEN ); + hCPE->hStereoClassif->xtalk_wscore_fx = floatToFixed( hCPE->hStereoClassif->xtalk_wscore, 31 ); +#endif + + stereo_dft_enc_compute_itd_fx( hCPE, pDFT_L_fx, DFT_L_e_tmp, pDFT_R_fx, DFT_R_e_tmp, k_offset, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_fx_e, bin_nrgR_fx, bin_nrgR_fx_e ); + + /*fix2flt*/ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS +#ifdef MSAN_FIX + hCPE->hStereoClassif->prev_ratio_m1_m2 = fixedToFloat( hCPE->hStereoClassif->prev_ratio_m1_m2_fx, Q31 ); + hCPE->hStereoClassif->prev_IPD = fixedToFloat( hCPE->hStereoClassif->prev_IPD_fx, Q29 ); +#endif + hStereoDft->sfm = fixedToFloat( hStereoDft->sfm_fx, 31 ); + me2f_buf( hStereoDft->xspec_smooth_fx, hStereoDft->xspec_smooth_fx_e, hStereoDft->xspec_smooth, STEREO_DFT_N_32k_ENC ); + me2f_buf( hStereoDft->Spd_L_smooth_fx, hStereoDft->Spd_L_smooth_fx_e, hStereoDft->Spd_L_smooth, STEREO_DFT_N_32k_ENC / 2 ); + me2f_buf( hStereoDft->Spd_R_smooth_fx, hStereoDft->Spd_R_smooth_fx_e, hStereoDft->Spd_R_smooth, STEREO_DFT_N_32k_ENC / 2 ); + fixedToFloat_arrL( hStereoDft->hItd->itd_fx, hStereoDft->hItd->itd, 16, STEREO_DFT_ENC_DFT_NB ); + fixedToFloat_arrL( hStereoDft->hItd->deltaItd_fx, hStereoDft->hItd->deltaItd, 16, STEREO_DFT_ENC_DFT_NB ); + fixedToFloat_arrL( hCPE->hStereoClassif->xtalk_fv_fx, hCPE->hStereoClassif->xtalk_fv, 15, SSC_MAX_NFEA ); + fixedToFloat_arrL( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, 15, SSC_MAX_NFEA ); + hCPE->hStereoClassif->ave_ener_L = me2f( hCPE->hStereoClassif->ave_ener_L_fx, hCPE->hStereoClassif->ave_ener_L_fx_e ); + hCPE->hStereoClassif->ave_ener_R = me2f( hCPE->hStereoClassif->ave_ener_R_fx, hCPE->hStereoClassif->ave_ener_R_fx_e ); + hStereoDft->hItd->prev_m1 = fixedToFloat( hStereoDft->hItd->prev_m1_fx, 31 ); + hStereoDft->hItd->prev_m2 = fixedToFloat( hStereoDft->hItd->prev_m2_fx, 31 ); + hCPE->hStereoClassif->xtalk_score = fixedToFloat( hCPE->hStereoClassif->xtalk_score_fx, 31 ); + fixedToFloat_arrL( hCPE->hStereoClassif->xtalk_score_buf_fx, hCPE->hStereoClassif->xtalk_score_buf, 31, XTALK_SCORE_BUF_LEN ); + hCPE->hStereoClassif->xtalk_wscore = fixedToFloat( hCPE->hStereoClassif->xtalk_wscore_fx, 31 ); +#endif +#else stereo_dft_enc_compute_itd( hCPE, pDFT_L, pDFT_R, k_offset, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL, bin_nrgR ); - if ( hCPE->element_mode == IVAS_CPE_MDCT ) +#endif + IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) ) { return; } - if ( hStereoDft->hItd->deltaItd[k_offset] != 0 && hStereoDft->hConfig->dmx_active ) + test(); + IF( hStereoDft->hItd->deltaItd_fx[k_offset] != 0 && hStereoDft->hConfig->dmx_active ) { /*time shift channels*/ - alpha = -2.0f * EVS_PI * hStereoDft->hItd->deltaItd[k_offset] / hStereoDft->NFFT; - c = 1.f; /*cos(0)*/ - s = 0.f; /*sin(0)*/ - c1 = cosf( alpha ); - s1 = sinf( alpha ); + // alpha = -2.0f * EVS_PI * hStereoDft->hItd->deltaItd[k_offset] / hStereoDft->NFFT; + alpha_fx = BASOP_Util_Divide3216_Scale( hStereoDft->hItd->deltaItd_fx[k_offset], hStereoDft->NFFT, &tmp_e ); + alpha_fx = negate( shl_r( mult_r( EVS_PI_FX, alpha_fx ), add( tmp_e, 1 ) ) ); // Q13*Q15= Q13 - if ( alpha >= 0 ) + // c = 1.f; /*cos(0)*/ + c_fx = MAX_16; /*cos(0)*/ + move16(); + // s = 0.f; /*sin(0)*/ + s_fx = 0; /*sin(0)*/ + move16(); + // c1 = cosf( alpha ); + c1_fx = shl_sat( getCosWord16( alpha_fx ), 1 ); + // s1 = sinf( alpha ); + s1_fx = getSinWord16( alpha_fx ); + + IF( alpha_fx >= 0 ) { - for ( i = 1; i < hStereoDft->NFFT / 2; i++ ) + FOR( i = 1; i < hStereoDft->NFFT / 2; i++ ) { - tmp = s * c1 + c * s1; - c = c * c1 - s * s1; - s = tmp; + // tmp = s * c1 + c * s1; + tmp_fx = add_sat( mult_r( s_fx, c1_fx ), mult_r( c_fx, s1_fx ) ); // saturation expected + // c = c * c1 - s * s1; + c_fx = sub_sat( mult_r( c_fx, c1_fx ), mult_r( s_fx, s1_fx ) ); // saturation expected + s_fx = tmp_fx; + move16(); /*time shift of L*/ - tmp = pDFT_L[2 * i] * c - pDFT_L[2 * i + 1] * s; - pDFT_L[2 * i + 1] = pDFT_L[2 * i] * s + pDFT_L[2 * i + 1] * c; - pDFT_L[2 * i] = tmp; + // tmp = pDFT_L[2 * i] * c - pDFT_L[2 * i + 1] * s; + tmp_32fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], c_fx ), DFT_L_e_tmp[2 * i], L_negate( Mpy_32_16_1( pDFT_L_fx[2 * i + 1], s_fx ) ), DFT_L_e_tmp[2 * i + 1], &tmp_e ); + // pDFT_L[2 * i + 1] = pDFT_L[2 * i] * s + pDFT_L[2 * i + 1] * c; + pDFT_L_fx[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_L_fx[2 * i], s_fx ), DFT_L_e_tmp[2 * i], Mpy_32_16_1( pDFT_L_fx[2 * i + 1], c_fx ), DFT_L_e_tmp[2 * i + 1], &DFT_L_e_tmp[2 * i + 1] ); + move32(); + // pDFT_L[2 * i] = tmp; + pDFT_L_fx[2 * i] = tmp_32fx; + move32(); + DFT_L_e_tmp[2 * i] = tmp_e; + move16(); } } - else + ELSE { - for ( i = 1; i < hStereoDft->NFFT / 2; i++ ) + FOR( i = 1; i < hStereoDft->NFFT / 2; i++ ) { - tmp = s * c1 + c * s1; - c = c * c1 - s * s1; - s = tmp; + // tmp = s * c1 + c * s1; + tmp_fx = add_sat( mult_r( s_fx, c1_fx ), mult_r( c_fx, s1_fx ) ); // saturation expected + // c = c * c1 - s * s1; + c_fx = sub_sat( mult_r( c_fx, c1_fx ), mult_r( s_fx, s1_fx ) ); // saturation expected + s_fx = tmp_fx; + move16(); /*time shift of R*/ - tmp = pDFT_R[2 * i] * c + pDFT_R[2 * i + 1] * s; - pDFT_R[2 * i + 1] = -pDFT_R[2 * i] * s + pDFT_R[2 * i + 1] * c; - pDFT_R[2 * i] = tmp; + // tmp = pDFT_R[2 * i] * c + pDFT_R[2 * i + 1] * s; + tmp_32fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pDFT_R_fx[2 * i], c_fx ), DFT_R_e_tmp[2 * i], Mpy_32_16_1( pDFT_R_fx[2 * i + 1], s_fx ), DFT_R_e_tmp[2 * i + 1], &tmp_e ); + // pDFT_R[2 * i + 1] = -pDFT_R[2 * i] * s + pDFT_R[2 * i + 1] * c; + pDFT_R_fx[2 * i + 1] = BASOP_Util_Add_Mant32Exp( L_negate( Mpy_32_16_1( pDFT_R_fx[2 * i], s_fx ) ), DFT_R_e_tmp[2 * i], Mpy_32_16_1( pDFT_R_fx[2 * i + 1], c_fx ), DFT_R_e_tmp[2 * i + 1], &DFT_R_e_tmp[2 * i + 1] ); + move32(); + // pDFT_R[2 * i] = tmp; + pDFT_R_fx[2 * i] = tmp_32fx; + move32(); + DFT_R_e_tmp[2 * i] = tmp_e; + move16(); } } - if ( fabsf( hStereoDft->hItd->deltaItd[k_offset] * 32000.f / input_Fs ) > 80.0f ) + // if ( fabsf( hStereoDft->hItd->deltaItd[k_offset] * 32000.f / input_Fs ) > 80.0f ) + tmp_32fx = L_abs( BASOP_Util_Divide3232_Scale_cadence( hStereoDft->hItd->deltaItd_fx[k_offset], input_Fs, &tmp_e ) ); + tmp_e = add( tmp_e, 15 - 31 ); + IF( BASOP_Util_Cmp_Mant32Exp( tmp_32fx, tmp_e, 5368709 /* 80.0f / 32000.f in Q31 */, 0 ) > 0 ) { - fac_att = min( 1.0f, max( 0.2f, 2.6f - 0.02f * fabsf( hStereoDft->hItd->deltaItd[1] ) * 32000.f / input_Fs ) ); + // fac_att = min( 1.0f, max( 0.2f, 2.6f - 0.02f * fabsf( hStereoDft->hItd->deltaItd[1] ) * 32000.f / input_Fs ) ); + tmp_fx = BASOP_Util_Divide3232_Scale( L_abs( hStereoDft->hItd->deltaItd_fx[1] ), input_Fs, &tmp_e ); + tmp_e = add( tmp_e, 15 - 31 ); + tmp_32fx = L_sub( 85197 /*2.6f in Q15*/, L_shl( L_mult0( tmp_fx, 640 /*0.02f * 32000.f in Q0*/ ), tmp_e ) ); // Q15 + fac_att_fx = extract_l( L_min( MAX_16, L_max( 6554 /*0.2f in Q15*/, tmp_32fx ) ) ); // Q15 } } /* compute remaining binwise energies for FB mode (ITD function only computes energies up to 16 kHz) */ - for ( i = STEREO_DFT_N_32k_ENC / 2; i < hStereoDft->NFFT / 2; i++ ) + FOR( i = STEREO_DFT_N_32k_ENC / 2; i < hStereoDft->NFFT / 2; i++ ) { - bin_nrgL[i] = pDFT_L[2 * i] * pDFT_L[2 * i] + pDFT_L[2 * i + 1] * pDFT_L[2 * i + 1]; - bin_nrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; + // bin_nrgL[i] = pDFT_L[2 * i] * pDFT_L[2 * i] + pDFT_L[2 * i + 1] * pDFT_L[2 * i + 1]; + bin_nrgL_fx[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L_fx[2 * i], pDFT_L_fx[2 * i] ), shl( DFT_L_e_tmp[2 * i], 1 ), Mpy_32_32( pDFT_L_fx[2 * i + 1], pDFT_L_fx[2 * i + 1] ), shl( DFT_L_e_tmp[2 * i + 1], 1 ), &bin_nrgL_fx_e[i] ); + move32(); + // bin_nrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; + bin_nrgR_fx[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_R_fx[2 * i], pDFT_R_fx[2 * i] ), shl( DFT_R_e_tmp[2 * i], 1 ), Mpy_32_32( pDFT_R_fx[2 * i + 1], pDFT_R_fx[2 * i + 1] ), shl( DFT_R_e_tmp[2 * i + 1], 1 ), &bin_nrgR_fx_e[i] ); + move32(); } } /* DFT stereo parameters */ - stereo_dft_enc_compute_prm( hStereoDft, pDFT_L, pDFT_R, k_offset, 1, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->vad_flag, bin_nrgL, bin_nrgR, dot_prod_nrg_ratio ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + floatToFixed_arrL( hStereoDft->side_gain, hStereoDft->side_gain_fx, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); + floatToFixed_arrL( hStereoDft->sidSideGain, hStereoDft->sidSideGain_fx, Q31, STEREO_DFT_ERB4_BANDS ); + floatToFixed_arrL( hStereoDft->gipd, hStereoDft->gipd_fx, Q13, STEREO_DFT_ENC_DFT_NB ); +#endif + stereo_dft_enc_compute_prm_fx( hStereoDft, pDFT_L_fx, DFT_L_e_tmp, pDFT_R_fx, DFT_R_e_tmp, k_offset, 1, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->vad_flag, bin_nrgL_fx, bin_nrgL_fx_e, bin_nrgR_fx, bin_nrgR_fx_e, dot_prod_nrg_ratio_fx, dot_prod_nrg_ratio_fx_e ); + // printf("\n%f ", (float)hStereoDft->res_pred_gain_fx[0] / 0x7fffffff); + // printf("\n%f ", (float)hStereoDft->sum_dot_prod_img_fx / powf(2, 31 - hStereoDft->sum_dot_prod_img_fx_e)); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arrL( hStereoDft->side_gain_fx, hStereoDft->side_gain, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); + fixedToFloat_arrL( hStereoDft->sidSideGain_fx, hStereoDft->sidSideGain, Q31, STEREO_DFT_ERB4_BANDS ); + fixedToFloat_arrL( hStereoDft->gipd_fx, hStereoDft->gipd, Q13, STEREO_DFT_ENC_DFT_NB ); + /*local fix2flt*/ + FOR( i = 0; i < CPE_CHANNELS; i++ ) + { + me2f_buf( hCPE->hStereoDft->DFT_fx[i], hCPE->hStereoDft->DFT_fx_e[i], hCPE->hStereoDft->DFT[i], STEREO_DFT_N_MAX_ENC ); + } + for ( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) + { + bin_nrgL[i] = me2f( bin_nrgL_fx[i], bin_nrgL_fx_e[i] ); + bin_nrgR[i] = me2f( bin_nrgR_fx[i], bin_nrgR_fx_e[i] ); + } + hCPE->hStereoDft->voicing_lt = fixedToFloat( hCPE->hStereoDft->voicing_lt_fx, 31 ); + fac_att = fixedToFloat( fac_att_fx, 15 ); + for ( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) + { + dot_prod_nrg_ratio[i] = me2f( dot_prod_nrg_ratio_fx[i], dot_prod_nrg_ratio_fx_e[i] ); + } + // fixedToFloat_arrL(dot_prod_nrg_ratio_fx, dot_prod_nrg_ratio, Q31, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX); + for ( i = 0; i < hStereoDft->NFFT; i++ ) + { + hStereoDft->DFT[0][i] = me2f( pDFT_L_fx[i], DFT_L_e_tmp[i] ); + hStereoDft->DFT[1][i] = me2f( pDFT_R_fx[i], DFT_R_e_tmp[i] ); + } +#endif if ( vad_flag_dtx[0] == 0 ) { @@ -2378,7 +2875,9 @@ void stereo_dft_enc_process( if ( hStereoDft->hConfig->dmx_active ) { /*Active DMX*/ - alpha = 0; /* to avoid compilation warning */ + // alpha = 0; /* to avoid compilation warning */ + alpha_fx = 0; /* to avoid compilation warning */ + move16(); g = 1.f; /*Apply active DMX*/ @@ -2639,9 +3138,6 @@ void stereo_dft_enc_process( { int16_t i, j, b; float *pDFT_L, *pDFT_R; -#ifdef IVAS_FLOAT_FIXED - Word32 *pDFT_L_fx, *pDFT_R_fx; -#endif float *pDFT_DMX; float *pDFT_RES; int16_t k_offset; @@ -2657,15 +3153,7 @@ void stereo_dft_enc_process( float DFT_RES[STEREO_DFT_N_8k_ENC]; int32_t input_Fs; float bin_nrgL[STEREO_DFT_N_MAX_ENC]; -#ifdef IVAS_FLOAT_FIXED - Word32 bin_nrgL_fx[STEREO_DFT_N_MAX_ENC]; - Word16 bin_nrgL_fx_e[STEREO_DFT_N_MAX_ENC]; -#endif float bin_nrgR[STEREO_DFT_N_MAX_ENC]; -#ifdef IVAS_FLOAT_FIXED - Word32 bin_nrgR_fx[STEREO_DFT_N_MAX_ENC]; - Word16 bin_nrgR_fx_e[STEREO_DFT_N_MAX_ENC]; -#endif float *pNrgL, *pNrgR; float res_nrg_all_curr, dmx_nrg_all_curr; float res_dmx_ratio, frame_nrg_ratio; @@ -2707,71 +3195,9 @@ void stereo_dft_enc_process( pDFT_L = hStereoDft->DFT[0]; pDFT_R = hStereoDft->DFT[1]; -#ifdef IVAS_FLOAT_FIXED - pDFT_L_fx = hStereoDft->DFT_fx[0]; - pDFT_R_fx = hStereoDft->DFT_fx[1]; -#endif - { -#ifdef IVAS_FLOAT_FIXED - /*flt2fix*/ - hStereoDft->sfm_fx = floatToFixed( hStereoDft->sfm, 31 ); - f2me_buf( hStereoDft->xspec_smooth, hStereoDft->xspec_smooth_fx, &hStereoDft->xspec_smooth_fx_e, STEREO_DFT_N_32k_ENC ); - f2me_buf( hStereoDft->Spd_L_smooth, hStereoDft->Spd_L_smooth_fx, &hStereoDft->Spd_L_smooth_fx_e, STEREO_DFT_N_32k_ENC / 2 ); - f2me_buf( hStereoDft->Spd_R_smooth, hStereoDft->Spd_R_smooth_fx, &hStereoDft->Spd_R_smooth_fx_e, STEREO_DFT_N_32k_ENC / 2 ); - floatToFixed_arrL( hStereoDft->hItd->itd, hStereoDft->hItd->itd_fx, 16, STEREO_DFT_ENC_DFT_NB ); - floatToFixed_arrL( hStereoDft->hItd->deltaItd, hStereoDft->hItd->deltaItd_fx, 16, STEREO_DFT_ENC_DFT_NB ); - floatToFixed_arrL( hCPE->hStereoClassif->xtalk_fv, hCPE->hStereoClassif->xtalk_fv_fx, 15, SSC_MAX_NFEA ); - floatToFixed_arrL( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, 15, SSC_MAX_NFEA ); - f2me( hCPE->hStereoClassif->ave_ener_L, &hCPE->hStereoClassif->ave_ener_L_fx, &hCPE->hStereoClassif->ave_ener_L_fx_e ); - f2me( hCPE->hStereoClassif->ave_ener_R, &hCPE->hStereoClassif->ave_ener_R_fx, &hCPE->hStereoClassif->ave_ener_R_fx_e ); - hStereoDft->hItd->prev_m1_fx = floatToFixed( hStereoDft->hItd->prev_m1, 31 ); - hStereoDft->hItd->prev_m2_fx = floatToFixed( hStereoDft->hItd->prev_m2, 31 ); - f2me( hStereoDft->hItd->currFlatness, &hStereoDft->hItd->currFlatness_fx, &hStereoDft->hItd->currFlatness_fx_e ); -#ifdef MSAN_FIX - hCPE->hStereoClassif->prev_IPD_fx = floatToFixed( hCPE->hStereoClassif->prev_IPD, Q29 ); - hCPE->hStereoClassif->prev_g_IPD_fx = floatToFixed( hCPE->hStereoClassif->prev_g_IPD, Q29 ); - hCPE->hStereoClassif->prev_ratio_m1_m2_fx = floatToFixed( hCPE->hStereoClassif->prev_ratio_m1_m2, Q31 ); -#endif - -#ifndef MSAN_FIX - hCPE->hStereoClassif->xtalk_score_fx = floatToFixed( hCPE->hStereoClassif->xtalk_score, 31 ); -#endif // !MSAN_FIX - floatToFixed_arrL( hCPE->hStereoClassif->xtalk_score_buf, hCPE->hStereoClassif->xtalk_score_buf_fx, 31, XTALK_SCORE_BUF_LEN ); - hCPE->hStereoClassif->xtalk_wscore_fx = floatToFixed( hCPE->hStereoClassif->xtalk_wscore, 31 ); - - stereo_dft_enc_compute_itd_fx( hCPE, pDFT_L_fx, hStereoDft->DFT_fx_e[0], pDFT_R_fx, hStereoDft->DFT_fx_e[1], k_offset, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL_fx, bin_nrgL_fx_e, bin_nrgR_fx, bin_nrgR_fx_e ); - - /*fix2flt*/ -#ifdef MSAN_FIX - hCPE->hStereoClassif->prev_ratio_m1_m2 = fixedToFloat( hCPE->hStereoClassif->prev_ratio_m1_m2_fx, Q31 ); - hCPE->hStereoClassif->prev_IPD = fixedToFloat( hCPE->hStereoClassif->prev_IPD_fx, Q29 ); -#endif - hStereoDft->sfm = fixedToFloat( hStereoDft->sfm_fx, 31 ); - me2f_buf( hStereoDft->xspec_smooth_fx, hStereoDft->xspec_smooth_fx_e, hStereoDft->xspec_smooth, STEREO_DFT_N_32k_ENC ); - me2f_buf( hStereoDft->Spd_L_smooth_fx, hStereoDft->Spd_L_smooth_fx_e, hStereoDft->Spd_L_smooth, STEREO_DFT_N_32k_ENC / 2 ); - me2f_buf( hStereoDft->Spd_R_smooth_fx, hStereoDft->Spd_R_smooth_fx_e, hStereoDft->Spd_R_smooth, STEREO_DFT_N_32k_ENC / 2 ); - fixedToFloat_arrL( hStereoDft->hItd->itd_fx, hStereoDft->hItd->itd, 16, STEREO_DFT_ENC_DFT_NB ); - fixedToFloat_arrL( hStereoDft->hItd->deltaItd_fx, hStereoDft->hItd->deltaItd, 16, STEREO_DFT_ENC_DFT_NB ); - fixedToFloat_arrL( hCPE->hStereoClassif->xtalk_fv_fx, hCPE->hStereoClassif->xtalk_fv, 15, SSC_MAX_NFEA ); - fixedToFloat_arrL( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, 15, SSC_MAX_NFEA ); - hCPE->hStereoClassif->ave_ener_L = me2f( hCPE->hStereoClassif->ave_ener_L_fx, hCPE->hStereoClassif->ave_ener_L_fx_e ); - hCPE->hStereoClassif->ave_ener_R = me2f( hCPE->hStereoClassif->ave_ener_R_fx, hCPE->hStereoClassif->ave_ener_R_fx_e ); - hStereoDft->hItd->prev_m1 = fixedToFloat( hStereoDft->hItd->prev_m1_fx, 31 ); - hStereoDft->hItd->prev_m2 = fixedToFloat( hStereoDft->hItd->prev_m2_fx, 31 ); - hCPE->hStereoClassif->xtalk_score = fixedToFloat( hCPE->hStereoClassif->xtalk_score_fx, 31 ); - fixedToFloat_arrL( hCPE->hStereoClassif->xtalk_score_buf_fx, hCPE->hStereoClassif->xtalk_score_buf, 31, XTALK_SCORE_BUF_LEN ); - hCPE->hStereoClassif->xtalk_wscore = fixedToFloat( hCPE->hStereoClassif->xtalk_wscore_fx, 31 ); - - /*local fix2flt*/ - for ( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) - { - bin_nrgL[i] = me2f( bin_nrgL_fx[i], bin_nrgL_fx_e[i] ); - bin_nrgR[i] = me2f( bin_nrgR_fx[i], bin_nrgR_fx_e[i] ); - } -#else + { stereo_dft_enc_compute_itd( hCPE, pDFT_L, pDFT_R, k_offset, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL, bin_nrgR ); -#endif if ( hCPE->element_mode == IVAS_CPE_MDCT ) { return; @@ -3126,712 +3552,671 @@ void stereo_dft_enc_process( return; } #endif -#else -void stereo_dft_enc_process( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const int16_t vad_flag_dtx[], /* i : VAD dtx flags */ - const int16_t vad_hover_flag[], /* i : VAD hangover flags */ - const int16_t input_frame /* i : input frame length */ -) +/*------------------------------------------------------------------------- + * stereo_dft_enc_get_res_cod_mode_flag() + * + * Get the residual signal coding flag + *-------------------------------------------------------------------------*/ + +static void stereo_dft_enc_get_res_cod_mode_flag( + STEREO_DFT_ENC_DATA_HANDLE hStereoDft, + const float res_nrg_all_curr, + const float dmx_nrg_all_curr, + float *res_dmx_ratio, + float *frame_nrg_ratio ) { - int16_t i, j, b; - float *pDFT_L, *pDFT_R; - float *pDFT_DMX; - float *pDFT_RES; - int16_t k_offset; - float *pgIpd; - float *pSideGain; - float c, alpha, g; - float wL, wR, wS; - float tmp; - float s, c1, s1; - float fac_att; - STEREO_DFT_ENC_DATA_HANDLE hStereoDft; - float DFT_DMX[STEREO_DFT_N_MAX_ENC]; - float DFT_RES[STEREO_DFT_N_8k_ENC]; - int32_t input_Fs; - float bin_nrgL[STEREO_DFT_N_MAX_ENC]; - float bin_nrgR[STEREO_DFT_N_MAX_ENC]; - float *pNrgL, *pNrgR; - float res_nrg_all_curr, dmx_nrg_all_curr; - float res_dmx_ratio, frame_nrg_ratio; - float dot_prod_nrg_ratio[STEREO_DFT_BAND_MAX]; /* contains only dot product for higher bands */ - float sum_nrg_L2, sum_nrg_R2, dot_prod_real2; - float sum_nrg_Mid, sum_abs; + int16_t b, k_offset; + float dmx_res_all, g; + int16_t fast_update_flag; + int16_t prev_res_cod_mode_flag, res_cod_mode_flag; - /*------------------------------------------------------------------* - * Initialization - *-----------------------------------------------------------------*/ + k_offset = STEREO_DFT_OFFSET; /*Add an offset at encoder*/ - input_Fs = input_frame * FRAMES_PER_SEC; + /*Calculate energy ratio between residual signal and downmix signal */ + *res_dmx_ratio = 0; - hStereoDft = hCPE->hStereoDft; + for ( b = 0; b < hStereoDft->res_cod_band_max; b++ ) + { + g = fabsf( hStereoDft->side_gain[(k_offset) *STEREO_DFT_BAND_MAX + b] ); + *res_dmx_ratio = max( hStereoDft->res_cod_NRG_S[b] / ( hStereoDft->res_cod_NRG_S[b] + ( 1 - g ) * ( 1 - g ) * hStereoDft->res_cod_NRG_M[b] + 1 ), *res_dmx_ratio ); + } + *res_dmx_ratio = check_bounds( *res_dmx_ratio, 0, 1 ); /*should always be satisfied*/ - wL = 0; /* avoid compilation warning */ - wR = 0; /* avoid compilation warning */ + /*Calculate the total energy of RES and DMX*/ + dmx_res_all = res_nrg_all_curr + dmx_nrg_all_curr; - /* Initialization */ - k_offset = STEREO_DFT_OFFSET; /*Add an offset at encoder*/ + /*Calculate the energy ratio of the inter-frame */ + *frame_nrg_ratio = dmx_res_all / hStereoDft->dmx_res_all_prev; + *frame_nrg_ratio = min( 5.0f, max( 0.2f, *frame_nrg_ratio ) ); - hStereoDft->gipd_band_max = dft_band_ipd[1][3]; - hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->band_res[k_offset]][hStereoDft->res_cod_mode[k_offset]]; - hStereoDft->res_cod_line_max = (int16_t) ( 0.5f + ( hStereoDft->band_limits[hStereoDft->res_cod_band_max] - 1 ) * 2.f * input_frame / (float) ( hStereoDft->NFFT ) ); - hStereoDft->res_cod_line_max = 8 * ( hStereoDft->res_cod_line_max / 8 ); - - hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); - - - hStereoDft->voicing_lt = 0.75f * hStereoDft->voicing_lt + 0.25f * hCPE->hCoreCoder[0]->voicing[0]; - hStereoDft->voicing_lt = 0.75f * hStereoDft->voicing_lt + 0.25f * hCPE->hCoreCoder[0]->voicing[1]; - - /*------------------------------------------------------------------* - * Compute stereo parameters - *-----------------------------------------------------------------*/ + /* Get fast update flag */ + fast_update_flag = 0; + if ( ( *frame_nrg_ratio > 3.2f && *res_dmx_ratio < 0.1f ) || ( *frame_nrg_ratio < 0.21f && *res_dmx_ratio > 0.4f ) ) + { + fast_update_flag = 1; + } - /*ITD in Frequency domain*/ - fac_att = 1.0f; + /* Calculate long term energy ratio between residual signal and downmix signal */ + if ( fast_update_flag ) + { + hStereoDft->res_dmx_ratio_lt = *res_dmx_ratio * 0.2f + hStereoDft->res_dmx_ratio_lt * 0.8f; + } + else + { + hStereoDft->res_dmx_ratio_lt = *res_dmx_ratio * 0.05f + hStereoDft->res_dmx_ratio_lt * 0.95f; + } - pDFT_L = hStereoDft->DFT[0]; - pDFT_R = hStereoDft->DFT[1]; + /*Get the residual signal coding initial flag */ + if ( hStereoDft->res_dmx_ratio_lt > 0.01f ) + { + res_cod_mode_flag = 1; + } + else + { + res_cod_mode_flag = 0; + } + /* Get the residual signal coding flag */ + if ( hStereoDft->first_frm_flag ) { - stereo_dft_enc_compute_itd( hCPE, pDFT_L, pDFT_R, k_offset, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL, bin_nrgR ); - if ( hCPE->element_mode == IVAS_CPE_MDCT ) + prev_res_cod_mode_flag = res_cod_mode_flag; + hStereoDft->first_frm_flag = 0; + } + else + { + prev_res_cod_mode_flag = hStereoDft->res_cod_mode[STEREO_DFT_OFFSET - 1]; + } + if ( res_cod_mode_flag != prev_res_cod_mode_flag ) + { + if ( prev_res_cod_mode_flag == 1 ) { - return; + if ( hStereoDft->hangover_cnt0 < 5 && hStereoDft->last_res_cod_mode_modify_flag == 0 && fast_update_flag == 0 ) + { + res_cod_mode_flag = prev_res_cod_mode_flag; + hStereoDft->hangover_cnt0++; + } + else + { + /* reset hangover */ + hStereoDft->hangover_cnt0 = 0; + } } - - if ( hStereoDft->hItd->deltaItd[k_offset] != 0 && hStereoDft->hConfig->dmx_active ) + else { - /*time shift channels*/ - alpha = -2.0f * EVS_PI * hStereoDft->hItd->deltaItd[k_offset] / hStereoDft->NFFT; - c = 1.f; /*cos(0)*/ - s = 0.f; /*sin(0)*/ - c1 = cosf( alpha ); - s1 = sinf( alpha ); - - if ( alpha >= 0 ) + if ( *frame_nrg_ratio > 2.5f || *frame_nrg_ratio < 0.21f ) { - for ( i = 1; i < hStereoDft->NFFT / 2; i++ ) - { - tmp = s * c1 + c * s1; - c = c * c1 - s * s1; - s = tmp; - - /*time shift of L*/ - tmp = pDFT_L[2 * i] * c - pDFT_L[2 * i + 1] * s; - pDFT_L[2 * i + 1] = pDFT_L[2 * i] * s + pDFT_L[2 * i + 1] * c; - pDFT_L[2 * i] = tmp; - } + /* reset hangover */ + hStereoDft->hangover_cnt1 = 0; } else { - for ( i = 1; i < hStereoDft->NFFT / 2; i++ ) + if ( hStereoDft->hangover_cnt1 < 5 ) { - tmp = s * c1 + c * s1; - c = c * c1 - s * s1; - s = tmp; - - /*time shift of R*/ - tmp = pDFT_R[2 * i] * c + pDFT_R[2 * i + 1] * s; - pDFT_R[2 * i + 1] = -pDFT_R[2 * i] * s + pDFT_R[2 * i + 1] * c; - pDFT_R[2 * i] = tmp; + res_cod_mode_flag = prev_res_cod_mode_flag; + hStereoDft->hangover_cnt1++; + } + else + { + /* reset hangover */ + hStereoDft->hangover_cnt1 = 0; } - } - - if ( fabsf( hStereoDft->hItd->deltaItd[k_offset] * 32000.f / input_Fs ) > 80.0f ) - { - fac_att = min( 1.0f, max( 0.2f, 2.6f - 0.02f * fabsf( hStereoDft->hItd->deltaItd[1] ) * 32000.f / input_Fs ) ); } } - - /* compute remaining binwise energies for FB mode (ITD function only computes energies up to 16 kHz) */ - for ( i = STEREO_DFT_N_32k_ENC / 2; i < hStereoDft->NFFT / 2; i++ ) - { - bin_nrgL[i] = pDFT_L[2 * i] * pDFT_L[2 * i] + pDFT_L[2 * i + 1] * pDFT_L[2 * i + 1]; - bin_nrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; - } } - /* DFT stereo parameters */ - stereo_dft_enc_compute_prm( hStereoDft, pDFT_L, pDFT_R, k_offset, 1, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->vad_flag, bin_nrgL, bin_nrgR, dot_prod_nrg_ratio ); - - if ( vad_flag_dtx[0] == 0 ) + /* handle switching frames */ + if ( res_cod_mode_flag != prev_res_cod_mode_flag && hStereoDft->last_res_cod_mode_modify_flag == 0 ) { - if ( hCPE->hStereoCng->cng_counter == 0 && !hCPE->hStereoCng->first_SID_after_TD ) + hStereoDft->res_cod_sw_flag = 1; + + /* Update switch_fade_factor */ + if ( *frame_nrg_ratio > 3.2f && *res_dmx_ratio < 0.1f ) { - hStereoDft->sid_gipd = hStereoDft->prev_sid_gipd; - hStereoDft->no_ipd_flag = hStereoDft->prev_sid_no_ipd_flag; + hStereoDft->switch_fade_factor = 0.75f; + } + else if ( *frame_nrg_ratio < 0.21f && *res_dmx_ratio > 0.4f ) + { + hStereoDft->switch_fade_factor = 0.25f; + } + else + { + hStereoDft->switch_fade_factor = 0.5f; } - if ( hCPE->hStereoCng->cng_counter > ITD_SID_PREV_FRAMES ) + if ( res_cod_mode_flag == 0 ) { - hStereoDft->prev_sid_gipd = hStereoDft->sid_gipd; - hStereoDft->prev_sid_no_ipd_flag = hStereoDft->no_ipd_flag; + res_cod_mode_flag = 1; } } - /*----------------------------------------------------------------* - * UNCLR classifier (detection of uncorrelated L and R channels) - *----------------------------------------------------------------*/ - - unclr_classifier_dft( hCPE ); + /*update previous frame's total energy of RES and DMX */ + hStereoDft->dmx_res_all_prev = dmx_res_all; - /*------------------------------------------------------------------* - * Channel mapping: computation of DMX and RES - *-----------------------------------------------------------------*/ + /* update residual coding mode */ + hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] = res_cod_mode_flag; + if ( !hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) + { + hStereoDft->res_cod_band_max = 0; + hStereoDft->res_cod_line_max = 0; + } - res_nrg_all_curr = EPSILON; - dmx_nrg_all_curr = EPSILON; + /*Update residual signal memory when switching from not coding residual signal to coding it*/ + if ( prev_res_cod_mode_flag == 0 && res_cod_mode_flag == 1 ) + { + set_zero( hStereoDft->output_mem_res_8k, STEREO_DFT_OVL_8k ); + } - pDFT_DMX = DFT_DMX; - pDFT_RES = DFT_RES; - pNrgL = bin_nrgL; - pNrgR = bin_nrgR; + return; +} - set_zero( pDFT_DMX, STEREO_DFT_N_MAX_ENC ); - set_zero( pDFT_RES, STEREO_DFT_N_8k_ENC ); +/*------------------------------------------------------------------------- + * stereo_dft_enc_res() + * + * Code the residual signal + *-------------------------------------------------------------------------*/ - pgIpd = hStereoDft->gipd + k_offset; - pSideGain = hStereoDft->side_gain + k_offset * STEREO_DFT_BAND_MAX; +void stereo_dft_enc_res( + STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ + const float *input_8k, /* i : input buffer sampled at 8kHz*/ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + int16_t *nb_bits, /* o : number of bits written */ + const int16_t max_bits ) +{ + int16_t i, b; + RangeUniEncState range_uni_enc_state; + ECSQ_instance ecsq_inst; + float MDCT_RES[L_FRAME8k]; + float win[L_FRAME8k + STEREO_DFT_OVL_8k]; + int16_t global_gain_index; + int16_t total_bit_count; + float max_snr; + float panning_gain, panning_gain_min; + float res_cod_gain[10]; + float in_phase_ratio; + assert( hStereoDft->res_cod_line_max <= L_FRAME8k ); - if ( hStereoDft->hConfig->dmx_active ) + if ( hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) { - /*Active DMX*/ - alpha = 0; /* to avoid compilation warning */ - g = 1.f; + /* Windowing */ + /* overlapping parts */ + /*input_8k-=STEREO_DFT_OVL_8k;*/ + for ( i = 0; i < STEREO_DFT_OVL_8k; i++ ) + { + win[i] = input_8k[i] * hStereoDft->win_mdct_8k[i]; + win[L_FRAME8k + i] = input_8k[L_FRAME8k + i] * hStereoDft->win_mdct_8k[STEREO_DFT_OVL_8k - 1 - i]; + } + /* middle part */ + for ( ; i < L_FRAME8k; i++ ) + { + win[i] = input_8k[i]; + } - /*Apply active DMX*/ - pDFT_DMX[0] = 0.f; - pDFT_RES[0] = 0.f; - for ( b = 0; b < hStereoDft->nbands_dmx; b++ ) + /* MDCT analysis */ + TCX_MDCT_flt( win, MDCT_RES, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + + /*Compute the DMX to RES for each band*/ + max_snr = 0.f; /*minimum gain for residual coding -> no coding*/ + for ( b = 0; b < hStereoDft->res_cod_band_max; b++ ) { - g = pSideGain[b]; + /*Get side gain information and it is we*/ + panning_gain = hStereoDft->side_gain[STEREO_DFT_OFFSET * STEREO_DFT_BAND_MAX + b]; + panning_gain_min = 1.f - fabsf( panning_gain ); - if ( pgIpd[0] != 0.f ) + in_phase_ratio = ( panning_gain_min * panning_gain_min * hStereoDft->res_cod_NRG_M[b] ) / ( panning_gain_min * panning_gain_min * hStereoDft->res_cod_NRG_M[b] + hStereoDft->res_cod_NRG_S[b] + 1 ); + in_phase_ratio = check_bounds( in_phase_ratio, 0, 1 ); + res_cod_gain[b] = in_phase_ratio * STEREO_DFT_RES_COD_SNR_MIN + ( 1 - in_phase_ratio ) * STEREO_DFT_RES_COD_SNR_MAX; + + /*get the maximum through bands*/ + if ( res_cod_gain[b] > max_snr ) { - c = cosf( pgIpd[0] ); - s = sinf( pgIpd[0] ); - for ( i = hStereoDft->band_limits_dmx[b]; i < hStereoDft->band_limits_dmx[b + 1]; i++ ) - { - /*rotate L*/ - tmp = pDFT_L[2 * i] * c + pDFT_L[2 * i + 1] * s; - pDFT_L[2 * i + 1] = pDFT_L[2 * i + 1] * c - pDFT_L[2 * i] * s; - pDFT_L[2 * i] = tmp; - } + max_snr = res_cod_gain[b]; } + } - if ( b < hStereoDft->res_cod_band_max && vad_flag_dtx[0] ) - { + /*Smooth max_snr because of several perturbations in computation*/ + hStereoDft->old_snr = 0.2f * max_snr + 0.8f * hStereoDft->old_snr; + max_snr = hStereoDft->old_snr; - /*Get the previous frame energy*/ - if ( hStereoDft->hConfig->ada_wb_res_cod_mode ) - { - /*Calculate the energy of RES and DMX*/ - /* 90% of old frame ... */ - dmx_nrg_all_curr += hStereoDft->res_cod_NRG_M[b] * 0.9f; - res_nrg_all_curr += hStereoDft->res_cod_NRG_S[b] * 0.9f; - } - hStereoDft->res_cod_NRG_M[b] = EPSILON; - hStereoDft->res_cod_NRG_S[b] = EPSILON; + if ( max_snr < STEREO_DFT_RES_COD_SNR_MIN ) + { + max_snr = STEREO_DFT_RES_COD_SNR_MIN; + } - for ( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) - { - pDFT_DMX[2 * i] = ( pDFT_L[2 * i] + pDFT_R[2 * i] ) * 0.5f; - pDFT_DMX[2 * i + 1] = ( pDFT_L[2 * i + 1] + pDFT_R[2 * i + 1] ) * 0.5f; + push_wmops( "residual_encode" ); + /* residual encoding */ + ECSQ_init_instance( &ecsq_inst, 0 /*dummy index*/, &range_uni_enc_state ); + rc_uni_enc_init( &range_uni_enc_state ); - pDFT_RES[2 * i] = ( pDFT_L[2 * i] - pDFT_R[2 * i] ) * 0.5f; - pDFT_RES[2 * i + 1] = ( pDFT_L[2 * i + 1] - pDFT_R[2 * i + 1] ) * 0.5f; + ecsq_inst.bit_count_estimate = 0; + ecsq_inst.config_index = 2 * hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] - 1; - /*Prediction of RES with DMX*/ - pDFT_RES[2 * i] = pDFT_RES[2 * i] - g * pDFT_DMX[2 * i]; - pDFT_RES[2 * i + 1] = pDFT_RES[2 * i + 1] - g * pDFT_DMX[2 * i + 1]; + /* 7 bits (STEREO_DFT_RES_GLOBAL_GAIN_BITS) for global_gain_index, 2 bits for closing of the arithmetic coder, 8 safety bits to account for the size estimation accuracy */ + ECSQ_encode_target_SNR( &ecsq_inst, MDCT_RES, hStereoDft->res_cod_line_max, max_snr, max_bits - ( *nb_bits ) - STEREO_DFT_RES_GLOBAL_GAIN_BITS - 2 - 8, NULL, &global_gain_index ); + if ( global_gain_index != ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) + { + total_bit_count = rc_uni_enc_finish( &range_uni_enc_state ); - pDFT_RES[2 * i] *= fac_att; - pDFT_RES[2 * i + 1] *= fac_att; + if ( total_bit_count <= max_bits - *nb_bits - STEREO_DFT_RES_GLOBAL_GAIN_BITS ) + { + int16_t idx; + uint8_t *byte_buffer; - /*Energy of the DMX and RES*/ - hStereoDft->res_cod_NRG_M[b] += pDFT_DMX[2 * i] * pDFT_DMX[2 * i] + pDFT_DMX[2 * i + 1] * pDFT_DMX[2 * i + 1]; - hStereoDft->res_cod_NRG_S[b] += pDFT_RES[2 * i] * pDFT_RES[2 * i] + pDFT_RES[2 * i + 1] * pDFT_RES[2 * i + 1]; - } + /* Global gain */ + push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); + ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; - if ( hStereoDft->hConfig->ada_wb_res_cod_mode ) + /* Push arithmetic coded bits */ + byte_buffer = range_uni_enc_state.byte_buffer; + for ( idx = 0; idx < ( total_bit_count >> 3 ); ++idx ) { - /*Calculate the energy of RES and DMX*/ - /* ... + 10% of current frame. */ - dmx_nrg_all_curr += hStereoDft->res_cod_NRG_M[b] * 0.1f; - res_nrg_all_curr += hStereoDft->res_cod_NRG_S[b] * 0.1f; + push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_COD, byte_buffer[idx], 8 ); + } + if ( ( total_bit_count & 7 ) != 0 ) + { + /* move the last 1 to 7 bits from the MSB position of the last byte to the LSB postion */ + push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_COD, byte_buffer[idx] >> ( 8 - ( total_bit_count & 7 ) ), total_bit_count & 7 ); } + ( *nb_bits ) += total_bit_count; } else { - int16_t upper_border; - int16_t triple_bin; - float frac_dot_prod; /* fraction of dot product according to energy ratio of current bins and whole band */ - float Sr, Si; - float comb_nrgL, comb_nrgR; + /* Global gain -> 127*/ + global_gain_index = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO; + push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); + ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; + } + } + else + { + /* Global gain -> 127*/ + push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); + ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; + } - upper_border = min( STEREO_DFT_DMX_CROSSOVER, hStereoDft->band_limits_dmx[b + 1] ); + pop_wmops(); + } - triple_bin = 0; - if ( upper_border > hStereoDft->band_limits_dmx[b] && ( upper_border - hStereoDft->band_limits_dmx[b] ) % 2 ) - { - /* if odd number of bins in band, combine last 3 bins */ - triple_bin = 1; - upper_border -= 3; - } - for ( i = hStereoDft->band_limits_dmx[b]; i < upper_border; i += 2 ) - { - comb_nrgL = pNrgL[i] + pNrgL[i + 1]; - comb_nrgR = pNrgR[i] + pNrgR[i + 1]; - Sr = ( pDFT_L[2 * i] + pDFT_R[2 * i] ) * ( pDFT_L[2 * i] + pDFT_R[2 * i] ) + ( pDFT_L[2 * i + 2] + pDFT_R[2 * i + 2] ) * ( pDFT_L[2 * i + 2] + pDFT_R[2 * i + 2] ); - Si = ( pDFT_L[2 * i + 1] + pDFT_R[2 * i + 1] ) * ( pDFT_L[2 * i + 1] + pDFT_R[2 * i + 1] ) + ( pDFT_L[2 * i + 3] + pDFT_R[2 * i + 3] ) * ( pDFT_L[2 * i + 3] + pDFT_R[2 * i + 3] ); + return; +} - sum_abs = sqrtf( comb_nrgL ) + sqrtf( comb_nrgR ) + EPSILON; - frac_dot_prod = ( comb_nrgL + comb_nrgR ) * dot_prod_nrg_ratio[b]; - wR = sqrtf( 0.5f * ( comb_nrgL + comb_nrgR ) + frac_dot_prod ) / sum_abs; - wL = wR + sqrtf( 2.f ) * ( 1.f - ( sqrtf( Sr + Si ) / sum_abs ) ); +/*------------------------------------------------------------------------- + * stereo_dft_enc_write_BS() + * + * Write DFT stereo bitstream + *-------------------------------------------------------------------------*/ - /*DMX Mapping*/ - pDFT_DMX[2 * i] = ( wL * pDFT_L[2 * i] + wR * pDFT_R[2 * i] ) * INV_SQRT_2; - pDFT_DMX[2 * i + 1] = ( wL * pDFT_L[2 * i + 1] + wR * pDFT_R[2 * i + 1] ) * INV_SQRT_2; - pDFT_DMX[2 * i + 2] = ( wL * pDFT_L[2 * i + 2] + wR * pDFT_R[2 * i + 2] ) * INV_SQRT_2; - pDFT_DMX[2 * i + 3] = ( wL * pDFT_L[2 * i + 3] + wR * pDFT_R[2 * i + 3] ) * INV_SQRT_2; - } +void stereo_dft_enc_write_BS( + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + int16_t *nb_bits /* o : number of bits written */ +) +{ + int16_t b, k_offset, itd, nb, nbands, sp_aud_decision0; + int16_t NFFT_inner, nbands_full; + int16_t no_GR_ord; + int16_t encoded_ind_GR[STEREO_DFT_BAND_MAX]; + int16_t encoded_ind_pred_GR[STEREO_DFT_BAND_MAX]; + int16_t sid_gIpd_index, sid_itd; + float cohBand[STEREO_DFT_BAND_MAX / 2]; + BSTR_ENC_HANDLE hBstr; + STEREO_DFT_ENC_DATA_HANDLE hStereoDft; + int32_t core_brate; - if ( triple_bin ) - { - comb_nrgL = comb_nrgR = 0.f; - Sr = Si = 0.f; - for ( j = i; j < i + 3; j++ ) - { - comb_nrgL += pNrgL[j]; - comb_nrgR += pNrgR[j]; - Sr += ( pDFT_L[2 * j] + pDFT_R[2 * j] ) * ( pDFT_L[2 * j] + pDFT_R[2 * j] ); - Si += ( pDFT_L[2 * j + 1] + pDFT_R[2 * j + 1] ) * ( pDFT_L[2 * j + 1] + pDFT_R[2 * j + 1] ); - } + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ - sum_abs = sqrtf( comb_nrgL ) + sqrtf( comb_nrgR ) + EPSILON; - frac_dot_prod = ( comb_nrgL + comb_nrgR ) * dot_prod_nrg_ratio[b]; - wR = sqrtf( 0.5f * ( comb_nrgL + comb_nrgR ) + frac_dot_prod ) / sum_abs; - wL = wR + sqrtf( 2.f ) * ( 1.f - ( sqrtf( Sr + Si ) / sum_abs ) ); + hStereoDft = hCPE->hStereoDft; + hBstr = hCPE->hMetaData; + core_brate = hCPE->hCoreCoder[0]->core_brate; - for ( j = i; j < i + 3; j++ ) - { - pDFT_DMX[2 * j] = ( wL * pDFT_L[2 * j] + wR * pDFT_R[2 * j] ) * INV_SQRT_2; - pDFT_DMX[2 * j + 1] = ( wL * pDFT_L[2 * j + 1] + wR * pDFT_R[2 * j + 1] ) * INV_SQRT_2; - } - i += 3; - } + sp_aud_decision0 = 0; + if ( hCPE->last_element_mode == IVAS_CPE_DFT ) + { + sp_aud_decision0 = hCPE->hCoreCoder[0]->sp_aud_decision0; + } - if ( i < hStereoDft->band_limits_dmx[b + 1] ) - { - sum_nrg_L2 = EPSILON; - sum_nrg_R2 = EPSILON; - dot_prod_real2 = EPSILON; - for ( j = hStereoDft->band_limits_dmx[b]; j < hStereoDft->band_limits_dmx[b + 1]; j++ ) - { - sum_nrg_L2 += pDFT_L[2 * j] * pDFT_L[2 * j] + pDFT_L[2 * j + 1] * pDFT_L[2 * j + 1]; - sum_nrg_R2 += pDFT_R[2 * j] * pDFT_R[2 * j] + pDFT_R[2 * j + 1] * pDFT_R[2 * j + 1]; - dot_prod_real2 += pDFT_L[2 * j] * pDFT_R[2 * j] + pDFT_L[2 * j + 1] * pDFT_R[2 * j + 1]; - } + *nb_bits = 0; + k_offset = STEREO_DFT_OFFSET; - sum_nrg_Mid = max( 0.f, sum_nrg_L2 + sum_nrg_R2 + 2.f * dot_prod_real2 ); - sum_abs = sqrtf( sum_nrg_L2 ) + sqrtf( sum_nrg_R2 ) + EPSILON; - wR = sqrtf( 0.5f * ( sum_nrg_L2 + sum_nrg_R2 ) + dot_prod_nrg_ratio[b] ) / sum_abs; - wL = wR + sqrtf( 2.f ) * ( 1.f - sqrtf( sum_nrg_Mid ) / sum_abs ); - } + nbands_full = hStereoDft->nbands; - for ( ; i < hStereoDft->band_limits_dmx[b + 1]; i++ ) - { - /*DMX Mapping*/ - pDFT_DMX[2 * i] = ( wL * pDFT_L[2 * i] + wR * pDFT_R[2 * i] ) * INV_SQRT_2; - pDFT_DMX[2 * i + 1] = ( wL * pDFT_L[2 * i + 1] + wR * pDFT_R[2 * i + 1] ) * INV_SQRT_2; - } - } - } + if ( core_brate == FRAME_NO_DATA || core_brate == SID_2k40 ) + { + NFFT_inner = min( STEREO_DFT_N_32k_ENC, STEREO_DFT_N_MAX_ENC * inner_frame_tbl[hCPE->hCoreCoder[0]->bwidth] / L_FRAME48k ); + hStereoDft->band_res[k_offset] = hStereoDft->hConfig->band_res; + hStereoDft->res_pred_mode[k_offset] = 0; + hStereoDft->res_cod_mode[k_offset] = 0; + } + else + { + NFFT_inner = STEREO_DFT_N_MAX_ENC * inner_frame_tbl[hCPE->hCoreCoder[0]->bwidth] / L_FRAME48k; + } - for ( i = hStereoDft->band_limits_dmx[b]; i < hStereoDft->NFFT / 2; i++ ) - { - pDFT_DMX[2 * i] = 0.f; - pDFT_DMX[2 * i + 1] = 0.f; - } + /* set number of bands according to bandwidth after BWD */ +#ifndef IVAS_FLOAT_FIXED + hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, ENC ); +#else + hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, ENC ); +#endif - /*Nyquist Freq.*/ - if ( hStereoDft->band_limits_dmx[b] >= hStereoDft->NFFT / 2 ) - { - pDFT_DMX[1] = ( pDFT_L[1] + pDFT_R[1] ) * 0.5f; - } - else - { - pDFT_DMX[1] = 0.f; - } + if ( core_brate == FRAME_NO_DATA ) + { + /* No data frame */ + ( *nb_bits ) = 0; + return; + } - /* DC component */ - pDFT_DMX[0] = ( pDFT_L[0] + pDFT_R[0] ) * 0.5f; + /* attack present */ + /* attackPresent not sent in inactive frames, receiver assumes = 0 */ + if ( core_brate != SID_2k40 ) + { + push_indice( hBstr, IND_STEREO_DFT_ATTACK_PRESENT, hStereoDft->attackPresent, 1 ); + ( *nb_bits )++; } - else + + /* Writing coding residual coding mode into bitstream */ + if ( hStereoDft->hConfig->ada_wb_res_cod_mode && hCPE->hCoreCoder[0]->bwidth == WB ) { - /*passive DMX*/ - assert( hStereoDft->nbands == hStereoDft->nbands_dmx && "Don't use coarser stereo parameter resolution for residual coding bitrates!" ); - for ( i = 0; i < hStereoDft->band_limits[hStereoDft->res_cod_band_max]; i++ ) - { - pDFT_DMX[i] = ( pDFT_L[i] + pDFT_R[i] ) * 0.5f; - pDFT_RES[i] = ( pDFT_L[i] - pDFT_R[i] ) * 0.5f; - } - for ( ; i < hStereoDft->NFFT; i++ ) - { - pDFT_DMX[i] = ( pDFT_L[i] + pDFT_R[i] ) * 0.5f; - } + push_indice( hBstr, IND_STEREO_DFT_RES_COD, hStereoDft->res_cod_mode[k_offset], 1 ); + ( *nb_bits )++; + hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->hConfig->band_res][hStereoDft->res_cod_mode[k_offset]]; + hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); } + + if ( nbands_full < hStereoDft->nbands ) + { + hStereoDft->reverb_flag = 0; + } + + /* Side gains */ + hStereoDft->side_gain_flag_1 = 0; /* EC coding by default */ + side_gain_mode_decision( hStereoDft, encoded_ind_GR, sp_aud_decision0, hCPE->hCoreCoder[0]->last_core_brate ); + + /* residual pred. gains */ + hStereoDft->res_pred_flag_1 = 0; /* EC coding by default */ + + res_pred_gain_mode_decision( hStereoDft, encoded_ind_pred_GR, k_offset, hCPE->hCoreCoder[0]->last_core_brate ); + /*------------------------------------------------------------------* - * Recalculate RES and DMX + * write ITD indices *-----------------------------------------------------------------*/ - if ( hStereoDft->NFFT == STEREO_DFT_N_16k_ENC && hStereoDft->hConfig->ada_wb_res_cod_mode ) + if ( core_brate != SID_2k40 ) { - stereo_dft_enc_get_res_cod_mode_flag( hStereoDft, res_nrg_all_curr, dmx_nrg_all_curr, &res_dmx_ratio, &frame_nrg_ratio ); + push_indice( hBstr, IND_STEREO_DFT_ITD_MODE, ( hStereoDft->hItd->itd[k_offset] != 0 ), STEREO_DFT_ITD_MODE_NBITS ); + ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ + } - if ( hStereoDft->res_cod_sw_flag ) + if ( core_brate != SID_2k40 ) + { + if ( hStereoDft->hItd->itd[k_offset] ) { - int16_t res_cod_band_max; - - res_cod_band_max = dft_band_res_cod[hStereoDft->band_res[k_offset]][hStereoDft->hConfig->ada_wb_res_cod_mode]; - - /* Recalculate RES and DMX */ - for ( b = 0; b < res_cod_band_max; b++ ) + itd = hStereoDft->hItd->itd_index[k_offset]; + if ( itd > 255 ) { - sum_nrg_L2 = EPSILON; - sum_nrg_R2 = EPSILON; - dot_prod_real2 = EPSILON; - for ( j = hStereoDft->band_limits_dmx[b]; j < hStereoDft->band_limits_dmx[b + 1]; j++ ) + itd -= 256; + + if ( itd < 20 ) { - sum_nrg_L2 += pDFT_L[2 * j] * pDFT_L[2 * j] + pDFT_L[2 * j + 1] * pDFT_L[2 * j + 1]; - sum_nrg_R2 += pDFT_R[2 * j] * pDFT_R[2 * j] + pDFT_R[2 * j + 1] * pDFT_R[2 * j + 1]; - dot_prod_real2 += pDFT_L[2 * j] * pDFT_R[2 * j] + pDFT_L[2 * j + 1] * pDFT_R[2 * j + 1]; + push_indice( hBstr, IND_STEREO_DFT_ITD_HUFF, 1, 1 ); /* use Huffman*/ + push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 1, 1 ); /* negative */ + push_indice( hBstr, IND_STEREO_DFT_ITD_COD, dft_code_itd[itd], dft_len_itd[itd] ); + ( *nb_bits ) += dft_len_itd[itd] + 2; } - - sum_nrg_Mid = max( 0.f, sum_nrg_L2 + sum_nrg_R2 + 2.f * dot_prod_real2 ); - wL = 0.5f * max( sqrtf( sum_nrg_L2 ) + sqrtf( sum_nrg_R2 ) - sqrtf( sum_nrg_Mid ), 0 ) * inv_sqrt( sum_nrg_L2 + EPSILON ); - wS = 1; - - if ( hStereoDft->res_cod_sw_flag ) + else { - wL *= ( 1 - hStereoDft->switch_fade_factor ); - wS = hStereoDft->switch_fade_factor; + push_indice( hBstr, IND_STEREO_DFT_ITD_HUFF, 0, 1 ); /* don't use Huffman */ + push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 1, 1 ); /* negative */ + push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_ITD_NBITS - 1 ); + ( *nb_bits ) += STEREO_DFT_ITD_NBITS + 1; } - - for ( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) + } + else + { + if ( itd < 20 ) { - /*DMX Recalculation*/ - DFT_DMX[2 * i] += wL * pDFT_L[2 * i]; - DFT_DMX[2 * i + 1] += wL * pDFT_L[2 * i + 1]; - - /*RES Recalculation*/ - DFT_RES[2 * i] *= wS; - DFT_RES[2 * i + 1] *= wS; + push_indice( hBstr, IND_STEREO_DFT_ITD_HUFF, 1, 1 ); /* use Huffman*/ + push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 0, 1 ); /* positive */ + push_indice( hBstr, IND_STEREO_DFT_ITD_COD, dft_code_itd[itd], dft_len_itd[itd] ); + ( *nb_bits ) += dft_len_itd[itd] + 2; + } + else + { + /* don't use Huffman and positive*/ + push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_ITD_NBITS + 1 ); + ( *nb_bits ) += STEREO_DFT_ITD_NBITS + 1; } } } } - if ( input_Fs >= 32000 ) - { - stereo_dft_enc_calculate_nrg_for_icbwe( hStereoDft, DFT_DMX, input_Fs ); - } - - mvr2r( DFT_DMX, hStereoDft->DFT[0], STEREO_DFT_N_MAX_ENC ); - mvr2r( DFT_RES, hStereoDft->DFT[1], STEREO_DFT_N_8k_ENC ); - set_zero( hStereoDft->DFT[1] + STEREO_DFT_N_8k_ENC, STEREO_DFT_N_MAX_ENC - STEREO_DFT_N_8k_ENC ); - - return; -} +#ifdef DEBUG_MODE_DFT_BITS + fprintf( ITD_bits, "%d ", *nb_bits ); #endif -/*------------------------------------------------------------------------- - * stereo_dft_enc_get_res_cod_mode_flag() - * - * Get the residual signal coding flag - *-------------------------------------------------------------------------*/ - -static void stereo_dft_enc_get_res_cod_mode_flag( - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, - const float res_nrg_all_curr, - const float dmx_nrg_all_curr, - float *res_dmx_ratio, - float *frame_nrg_ratio ) -{ - int16_t b, k_offset; - float dmx_res_all, g; - int16_t fast_update_flag; - int16_t prev_res_cod_mode_flag, res_cod_mode_flag; - - k_offset = STEREO_DFT_OFFSET; /*Add an offset at encoder*/ - - /*Calculate energy ratio between residual signal and downmix signal */ - *res_dmx_ratio = 0; - - for ( b = 0; b < hStereoDft->res_cod_band_max; b++ ) - { - g = fabsf( hStereoDft->side_gain[(k_offset) *STEREO_DFT_BAND_MAX + b] ); - *res_dmx_ratio = max( hStereoDft->res_cod_NRG_S[b] / ( hStereoDft->res_cod_NRG_S[b] + ( 1 - g ) * ( 1 - g ) * hStereoDft->res_cod_NRG_M[b] + 1 ), *res_dmx_ratio ); - } - *res_dmx_ratio = check_bounds( *res_dmx_ratio, 0, 1 ); /*should always be satisfied*/ - - /*Calculate the total energy of RES and DMX*/ - dmx_res_all = res_nrg_all_curr + dmx_nrg_all_curr; - - /*Calculate the energy ratio of the inter-frame */ - *frame_nrg_ratio = dmx_res_all / hStereoDft->dmx_res_all_prev; - *frame_nrg_ratio = min( 5.0f, max( 0.2f, *frame_nrg_ratio ) ); - /* Get fast update flag */ - fast_update_flag = 0; - if ( ( *frame_nrg_ratio > 3.2f && *res_dmx_ratio < 0.1f ) || ( *frame_nrg_ratio < 0.21f && *res_dmx_ratio > 0.4f ) ) - { - fast_update_flag = 1; - } + /*------------------------------------------------------------------* + * write Side gain indices + *-----------------------------------------------------------------*/ - /* Calculate long term energy ratio between residual signal and downmix signal */ - if ( fast_update_flag ) + /* Side Gain flag 1 */ + nb = 0; + if ( hStereoDft->side_gain_flag_1 > 0 ) { - hStereoDft->res_dmx_ratio_lt = *res_dmx_ratio * 0.2f + hStereoDft->res_dmx_ratio_lt * 0.8f; + push_indice( hBstr, IND_STEREO_DFT_SIDEGAIN_FLAG, hStereoDft->side_gain_flag_1, 2 ); + nb += 2; } else { - hStereoDft->res_dmx_ratio_lt = *res_dmx_ratio * 0.05f + hStereoDft->res_dmx_ratio_lt * 0.95f; + push_indice( hBstr, IND_STEREO_DFT_SIDEGAIN_FLAG, hStereoDft->side_gain_flag_1, STEREO_DFT_FLAG_BITS ); + nb += STEREO_DFT_FLAG_BITS; } - /*Get the residual signal coding initial flag */ - if ( hStereoDft->res_dmx_ratio_lt > 0.01f ) - { - res_cod_mode_flag = 1; - } - else - { - res_cod_mode_flag = 0; - } + no_GR_ord = 3; - /* Get the residual signal coding flag */ - if ( hStereoDft->first_frm_flag ) + if ( hStereoDft->side_gain_flag_1 == 0 ) { - prev_res_cod_mode_flag = res_cod_mode_flag; - hStereoDft->first_frm_flag = 0; + nb += write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, encoded_ind_GR, hStereoDft->nbands, hStereoDft->side_gain_flag_2, no_GR_ord ); } else { - prev_res_cod_mode_flag = hStereoDft->res_cod_mode[STEREO_DFT_OFFSET - 1]; - } - if ( res_cod_mode_flag != prev_res_cod_mode_flag ) - { - if ( prev_res_cod_mode_flag == 1 ) + if ( hStereoDft->side_gain_flag_1 == 2 ) { - if ( hStereoDft->hangover_cnt0 < 5 && hStereoDft->last_res_cod_mode_modify_flag == 0 && fast_update_flag == 0 ) - { - res_cod_mode_flag = prev_res_cod_mode_flag; - hStereoDft->hangover_cnt0++; - } - else + nb += write_bitstream_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, hStereoDft->side_gain_index_ECDiff, hStereoDft->nbands, hStereoDft->side_gain_flag_2 - no_GR_ord ); + } + else + { + for ( b = 0; b < hStereoDft->nbands; b++ ) { - /* reset hangover */ - hStereoDft->hangover_cnt0 = 0; + /*ILD*/ + push_indice( hBstr, IND_STEREO_DFT_SIDEGAINS, hStereoDft->side_gain_index_EC[b], STEREO_DFT_SIDEGAIN_NBITS ); + nb += STEREO_DFT_SIDEGAIN_NBITS; } } - else + } + + /* nb bits are used for side gain*/ + ( *nb_bits ) += nb; +#ifdef DEBUG_MODE_DFT_BITS + fprintf( SG_bits, "%d ", nb ); +#endif + nb = 0; + + if ( core_brate == SID_2k40 ) + { + stereo_dft_enc_sid_calc_coh( hStereoDft, hCPE->hStereoCng->prev_cohBand, &hCPE->hStereoCng->td_active, &hCPE->hStereoCng->first_SID, cohBand ); + + if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 ) ) { - if ( *frame_nrg_ratio > 2.5f || *frame_nrg_ratio < 0.21f ) + if ( hStereoDft->hItd->itd[k_offset] != 0 ) { - /* reset hangover */ - hStereoDft->hangover_cnt1 = 0; + /* Re-quantize ITD with lower resolution for Stereo CNG */ + itd = hStereoDft->hItd->itd_index[k_offset]; + if ( itd > 255 ) + { + itd -= 256; + } + itd = itd >> STEREO_DFT_SID_ITD_FAC; + + sid_itd = itd && 1; } else { - if ( hStereoDft->hangover_cnt1 < 5 ) + sid_itd = 0; + } + + push_indice( hBstr, IND_STEREO_DFT_ITD_MODE, sid_itd, STEREO_DFT_ITD_MODE_NBITS ); + ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ + + if ( sid_itd ) + { + itd = hStereoDft->hItd->itd_index[k_offset]; + if ( itd > 255 ) { - res_cod_mode_flag = prev_res_cod_mode_flag; - hStereoDft->hangover_cnt1++; + itd -= 256; + itd = itd >> STEREO_DFT_SID_ITD_FAC; + + if ( itd > ( ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1 ) ) + { + itd = ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1; + } + + push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 1, 1 ); /* negative */ + push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_SID_ITD_NBITS ); + ( *nb_bits ) += STEREO_DFT_SID_ITD_NBITS + 1; } else { - /* reset hangover */ - hStereoDft->hangover_cnt1 = 0; + itd = itd >> STEREO_DFT_SID_ITD_FAC; + + if ( itd > ( ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1 ) ) + { + itd = ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1; + } + + push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 0, 1 ); /* Positive */ + push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_SID_ITD_NBITS ); + ( *nb_bits ) += STEREO_DFT_SID_ITD_NBITS + 1; } } } } - /* handle switching frames */ - if ( res_cod_mode_flag != prev_res_cod_mode_flag && hStereoDft->last_res_cod_mode_modify_flag == 0 ) - { - hStereoDft->res_cod_sw_flag = 1; + /*------------------------------------------------------------------* + * write IPD indices + *-----------------------------------------------------------------*/ - /* Update switch_fade_factor */ - if ( *frame_nrg_ratio > 3.2f && *res_dmx_ratio < 0.1f ) - { - hStereoDft->switch_fade_factor = 0.75f; - } - else if ( *frame_nrg_ratio < 0.21f && *res_dmx_ratio > 0.4f ) - { - hStereoDft->switch_fade_factor = 0.25f; - } - else - { - hStereoDft->switch_fade_factor = 0.5f; - } + if ( core_brate != SID_2k40 ) + { + push_indice( hBstr, IND_STEREO_DFT_NO_IPD_FLAG, hStereoDft->no_ipd_flag, STEREO_DFT_FLAG_BITS ); + nb += STEREO_DFT_FLAG_BITS; /*IPD mode flag: 1bit*/ - if ( res_cod_mode_flag == 0 ) + if ( hStereoDft->no_ipd_flag == 0 ) { - res_cod_mode_flag = 1; + push_indice( hBstr, IND_STEREO_DFT_GIPD, hStereoDft->gipd_index, STEREO_DFT_GIPD_NBITS ); + nb += STEREO_DFT_GIPD_NBITS; } } - - /*update previous frame's total energy of RES and DMX */ - hStereoDft->dmx_res_all_prev = dmx_res_all; - - /* update residual coding mode */ - hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] = res_cod_mode_flag; - if ( !hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) + else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS ) ) { - hStereoDft->res_cod_band_max = 0; - hStereoDft->res_cod_line_max = 0; - } + push_indice( hBstr, IND_STEREO_DFT_NO_IPD_FLAG, hStereoDft->no_ipd_flag, STEREO_DFT_FLAG_BITS ); + nb += STEREO_DFT_FLAG_BITS; /*IPD mode flag: 1bit*/ - /*Update residual signal memory when switching from not coding residual signal to coding it*/ - if ( prev_res_cod_mode_flag == 0 && res_cod_mode_flag == 1 ) - { - set_zero( hStereoDft->output_mem_res_8k, STEREO_DFT_OVL_8k ); + if ( hStereoDft->no_ipd_flag == 0 ) + { + stereo_dft_quantize_ipd( &hStereoDft->sid_gipd, &hStereoDft->sid_gipd, &sid_gIpd_index, STEREO_DFT_SID_GIPD_NBITS ); + push_indice( hBstr, IND_STEREO_DFT_GIPD, sid_gIpd_index, STEREO_DFT_SID_GIPD_NBITS ); + nb += STEREO_DFT_SID_GIPD_NBITS; + } } - return; -} -/*------------------------------------------------------------------------- - * stereo_dft_enc_res() - * - * Code the residual signal - *-------------------------------------------------------------------------*/ +#ifdef DEBUG_MODE_DFT_BITS + fprintf( IPD_bits, "%d ", nb ); +#endif + ( *nb_bits ) += nb; -void stereo_dft_enc_res( - STEREO_DFT_ENC_DATA_HANDLE hStereoDft, /* i/o: encoder stereo handle */ - const float *input_8k, /* i : input buffer sampled at 8kHz*/ - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - int16_t *nb_bits, /* o : number of bits written */ - const int16_t max_bits ) -{ - int16_t i, b; - RangeUniEncState range_uni_enc_state; - ECSQ_instance ecsq_inst; - float MDCT_RES[L_FRAME8k]; - float win[L_FRAME8k + STEREO_DFT_OVL_8k]; - int16_t global_gain_index; - int16_t total_bit_count; - float max_snr; - float panning_gain, panning_gain_min; - float res_cod_gain[10]; - float in_phase_ratio; - assert( hStereoDft->res_cod_line_max <= L_FRAME8k ); + /*----------------------------------------------------------------* + * Residual prediction + *----------------------------------------------------------------*/ - if ( hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) + nb = 0; /* bits for residual pred gains */ + if ( hStereoDft->res_pred_mode[k_offset] ) { - /* Windowing */ - /* overlapping parts */ - /*input_8k-=STEREO_DFT_OVL_8k;*/ - for ( i = 0; i < STEREO_DFT_OVL_8k; i++ ) - { - win[i] = input_8k[i] * hStereoDft->win_mdct_8k[i]; - win[L_FRAME8k + i] = input_8k[L_FRAME8k + i] * hStereoDft->win_mdct_8k[STEREO_DFT_OVL_8k - 1 - i]; - } - /* middle part */ - for ( ; i < L_FRAME8k; i++ ) - { - win[i] = input_8k[i]; - } - - /* MDCT analysis */ - TCX_MDCT_flt( win, MDCT_RES, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); - - /*Compute the DMX to RES for each band*/ - max_snr = 0.f; /*minimum gain for residual coding -> no coding*/ - for ( b = 0; b < hStereoDft->res_cod_band_max; b++ ) + if ( hStereoDft->attackPresent == 0 ) { - /*Get side gain information and it is we*/ - panning_gain = hStereoDft->side_gain[STEREO_DFT_OFFSET * STEREO_DFT_BAND_MAX + b]; - panning_gain_min = 1.f - fabsf( panning_gain ); - - in_phase_ratio = ( panning_gain_min * panning_gain_min * hStereoDft->res_cod_NRG_M[b] ) / ( panning_gain_min * panning_gain_min * hStereoDft->res_cod_NRG_M[b] + hStereoDft->res_cod_NRG_S[b] + 1 ); - in_phase_ratio = check_bounds( in_phase_ratio, 0, 1 ); - res_cod_gain[b] = in_phase_ratio * STEREO_DFT_RES_COD_SNR_MIN + ( 1 - in_phase_ratio ) * STEREO_DFT_RES_COD_SNR_MAX; + nbands = min( hStereoDft->nbands, STEREO_DFT_RES_PRED_BAND_MAX ); + b = hStereoDft->res_pred_band_min; - /*get the maximum through bands*/ - if ( res_cod_gain[b] > max_snr ) + /*Adaptive SF*/ + if ( hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) { - max_snr = res_cod_gain[b]; + /*read flag*/ + push_indice( hBstr, IND_STEREO_DFT_REVERB_MODE, hStereoDft->reverb_flag, STEREO_DFT_REVERB_MODE_NBITS ); + nb += STEREO_DFT_REVERB_MODE_NBITS; + if ( hStereoDft->reverb_flag ) + { + nbands -= STEREO_DFT_RES_PRED_BAND_MIN_CONST; + } } - } - - /*Smooth max_snr because of several perturbations in computation*/ - hStereoDft->old_snr = 0.2f * max_snr + 0.8f * hStereoDft->old_snr; - max_snr = hStereoDft->old_snr; - - if ( max_snr < STEREO_DFT_RES_COD_SNR_MIN ) - { - max_snr = STEREO_DFT_RES_COD_SNR_MIN; - } - - push_wmops( "residual_encode" ); - /* residual encoding */ - ECSQ_init_instance( &ecsq_inst, 0 /*dummy index*/, &range_uni_enc_state ); - rc_uni_enc_init( &range_uni_enc_state ); - - ecsq_inst.bit_count_estimate = 0; - ecsq_inst.config_index = 2 * hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] - 1; - - /* 7 bits (STEREO_DFT_RES_GLOBAL_GAIN_BITS) for global_gain_index, 2 bits for closing of the arithmetic coder, 8 safety bits to account for the size estimation accuracy */ - ECSQ_encode_target_SNR( &ecsq_inst, MDCT_RES, hStereoDft->res_cod_line_max, max_snr, max_bits - ( *nb_bits ) - STEREO_DFT_RES_GLOBAL_GAIN_BITS - 2 - 8, NULL, &global_gain_index ); - if ( global_gain_index != ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) - { - total_bit_count = rc_uni_enc_finish( &range_uni_enc_state ); - if ( total_bit_count <= max_bits - *nb_bits - STEREO_DFT_RES_GLOBAL_GAIN_BITS ) + /* Res Pred Gain flag 0 */ + if ( hStereoDft->res_pred_flag_1 > 0 ) { - int16_t idx; - uint8_t *byte_buffer; - - /* Global gain */ - push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); - ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; + push_indice( hBstr, IND_STEREO_DFT_RES_PRED_FLAG, hStereoDft->res_pred_flag_1, 2 ); + nb += 2; /*pred gain mode flag: 2 bits*/ + } + else + { + push_indice( hBstr, IND_STEREO_DFT_RES_PRED_FLAG, hStereoDft->res_pred_flag_1, STEREO_DFT_FLAG_BITS ); + nb += STEREO_DFT_FLAG_BITS; /*pred gain mode flag: 1bit*/ + } - /* Push arithmetic coded bits */ - byte_buffer = range_uni_enc_state.byte_buffer; - for ( idx = 0; idx < ( total_bit_count >> 3 ); ++idx ) + no_GR_ord = 2; + if ( hStereoDft->res_pred_flag_1 == 0 ) + { + if ( encoded_ind_pred_GR[0] == dft_maps_rpg[8 * NO_SYMB_GR_PRED_G] ) { - push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_COD, byte_buffer[idx], 8 ); + nb += write_GR1( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, 1 ); } - if ( ( total_bit_count & 7 ) != 0 ) + else { - /* move the last 1 to 7 bits from the MSB position of the last byte to the LSB postion */ - push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_COD, byte_buffer[idx] >> ( 8 - ( total_bit_count & 7 ) ), total_bit_count & 7 ); + nb += write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2, 2 ); } - ( *nb_bits ) += total_bit_count; } else { - /* Global gain -> 127*/ - global_gain_index = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO; - push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); - ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; + if ( hStereoDft->res_pred_flag_1 == 2 ) + { + nb += write_bitstream_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2 - no_GR_ord ); + } + else + { + for ( b = hStereoDft->res_pred_band_min; b < nbands; b++ ) + { + push_indice( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, hStereoDft->res_pred_index_EC[b], STEREO_DFT_RES_GAINS_BITS ); + nb += STEREO_DFT_RES_GAINS_BITS; + } + } } } else { - /* Global gain -> 127*/ - push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); - ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; + set_s( hStereoDft->res_pred_index_ECprevious, 0, hStereoDft->nbands - hStereoDft->res_pred_band_min ); } + } + else + { + set_s( hStereoDft->res_pred_index_ECprevious, 0, hStereoDft->nbands - hStereoDft->res_pred_band_min ); + } - pop_wmops(); + ( *nb_bits ) += nb; + + if ( core_brate == SID_2k40 ) + { + stereo_dft_enc_sid_coh( hBstr, hCPE->hStereoCng->mem_cohBand, hStereoDft->nbands, nb_bits, cohBand ); } @@ -3840,396 +4225,795 @@ void stereo_dft_enc_res( /*------------------------------------------------------------------------- - * stereo_dft_enc_write_BS() + * stereo_dft_enc_compute_prm() * - * Write DFT stereo bitstream - *-------------------------------------------------------------------------*/ + * Compute stereo parameters: IPD and SIDE_GAIN + * SIDE_GAIN: Interchannel Level Difference + * IPD: Interchannel Phase Difference: angle(L)-angle(R) = acos(/(|L|.|R|)) or atan2(Img(L.R*)/Re(L.R*)) + *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED -void stereo_dft_enc_write_BS( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - int16_t *nb_bits /* o : number of bits written */ -) +static void stereo_dft_enc_compute_prm_fx( + STEREO_DFT_ENC_DATA_HANDLE hStereoDft, + Word32 *DFT_L_fx, // Q(31-DFT_L_fx_e[]) + Word16 *DFT_L_fx_e, + Word32 *DFT_R_fx, // Q(31-DFT_R_fx_e[]) + Word16 *DFT_R_fx_e, + Word16 k_offset, + Word16 flag_quant, + const Word16 sp_aud_decision0, + const Word16 vad_flag, + Word32 *bin_nrgL_fx, // Q(31-bin_nrgL_fx_e[]) + Word16 *bin_nrgL_fx_e, + Word32 *bin_nrgR_fx, // Q(31-bin_nrgR_fx_e[]) + Word16 *bin_nrgR_fx_e, + Word32 *dot_prod_nrg_ratio_fx, // Q(31-dot_prod_nrg_ratio_fx_e[]) + Word16 *dot_prod_nrg_ratio_fx_e ) { - int16_t b, k_offset, itd, nb, nbands, sp_aud_decision0; - int16_t NFFT_inner, nbands_full; - int16_t no_GR_ord; - int16_t encoded_ind_GR[STEREO_DFT_BAND_MAX]; - int16_t encoded_ind_pred_GR[STEREO_DFT_BAND_MAX]; - int16_t sid_gIpd_index, sid_itd; - float cohBand[STEREO_DFT_BAND_MAX / 2]; - BSTR_ENC_HANDLE hBstr; - STEREO_DFT_ENC_DATA_HANDLE hStereoDft; - int32_t core_brate; + int16_t b, i; + int16_t b2; + Word32 *pDFT_L, *pDFT_R; + // Word16 DFT_L_e, DFT_R_e; + Word32 sum_nrg_L, sum_nrg_R; + Word16 sum_nrg_L_e, sum_nrg_R_e; + Word32 dot_prod_real, dot_prod_img; + Word16 dot_prod_real_e, dot_prod_img_e; + Word32 sum_nrg_L2, sum_nrg_R2; + Word16 sum_nrg_L2_e, sum_nrg_R2_e; + Word32 dot_prod_real2, dot_prod_img2; + Word16 dot_prod_real2_e, dot_prod_img2_e; + Word32 *pPredGain; + Word32 *pSideGain; + Word32 sum_energy_L, sum_energy_R; + Word16 sum_energy_L_e, sum_energy_R_e; + Word32 g, c; + Word16 /*g,*/ c_e; + Word32 abs_L_R; + Word16 abs_L_R_e; + Word32 abs_L_R2; + Word16 abs_L_R2_e; + Word32 gain_IPD; // Q31 + Word32 sub_nrg_DMX[STEREO_DFT_BAND_MAX]; + Word16 sub_nrg_DMX_e[STEREO_DFT_BAND_MAX]; + Word32 sub_nrg_DMX2; + Word16 sub_nrg_DMX2_e; + Word32 sub_nrg_L[STEREO_DFT_BAND_MAX]; + Word16 sub_nrg_L_e[STEREO_DFT_BAND_MAX]; + Word32 sub_nrg_R[STEREO_DFT_BAND_MAX]; + Word16 sub_nrg_R_e[STEREO_DFT_BAND_MAX]; + Word32 diff_ipd; + Word32 *pNrgL, *pNrgR; + Word16 *pNrgL_e, *pNrgR_e; + Word32 reg; + Word16 reg_e; + Word32 *pgIpd, sum_dot_prod_real, sum_dot_prod_img; + Word16 sum_dot_prod_real_e, sum_dot_prod_img_e; + Word32 sum_past_nrgL, sum_past_nrgL2; + Word16 sum_past_nrgL_e, sum_past_nrgL2_e; + Word32 sum_past_nrgR, sum_past_nrgR2; + Word16 sum_past_nrgR_e, sum_past_nrgR2_e; + Word32 sum_past_dpr, sum_past_dpr2; + Word16 sum_past_dpr_e, sum_past_dpr2_e; + Word32 sum_past_dpi, sum_past_dpi2; + Word16 sum_past_dpi_e, sum_past_dpi2_e; + Word32 sum_past_dot_prod_abs, sum_past_dot_prod_abs2; + Word16 sum_past_dot_prod_abs_e, sum_past_dot_prod_abs2_e = 0; + Word32 sum_past_nrg_dmx; + Word16 sum_past_nrg_dmx_e; + int16_t pos; + Word32 pIpd[STEREO_DFT_BAND_MAX]; // Q13 + Word32 ipd_smooth[STEREO_DFT_BAND_MAX]; // Q13 + Word32 ipd_mean_change; // Q13 + + Word32 L_tmp; + Word16 L_tmp_e; + Word32 L_tmp1; + Word16 L_tmp1_e; + Word32 L_tmp2; + Word16 L_tmp2_e; + Word64 W_tmp; + Word16 W_shift; + move16(); + + /*Word16 past_nrgL_fx_tmp_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word16 past_nrgR_fx_tmp_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word16 past_dot_prod_real_fx_tmp_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + Word16 past_dot_prod_imag_fx_tmp_e[STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX]; + set16_fx(past_nrgL_fx_tmp_e, hStereoDft->past_nrgL_fx_e, STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX); + set16_fx(past_nrgR_fx_tmp_e, hStereoDft->past_nrgR_fx_e, STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX); + set16_fx(past_dot_prod_real_fx_tmp_e, hStereoDft->past_dot_prod_real_fx_e, STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX); + set16_fx(past_dot_prod_imag_fx_tmp_e, hStereoDft->past_dot_prod_imag_fx_e, STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX);*/ /*------------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ - hStereoDft = hCPE->hStereoDft; - hBstr = hCPE->hMetaData; - core_brate = hCPE->hCoreCoder[0]->core_brate; + sum_past_dot_prod_abs2 = 0; + move16(); + pos = hStereoDft->nrg_past_pos; + move16(); - sp_aud_decision0 = 0; - if ( hCPE->last_element_mode == IVAS_CPE_DFT ) - { - sp_aud_decision0 = hCPE->hCoreCoder[0]->sp_aud_decision0; - } + set32_fx( sub_nrg_DMX, 0, STEREO_DFT_BAND_MAX ); + set32_fx( sub_nrg_L, 0, STEREO_DFT_BAND_MAX ); + set32_fx( sub_nrg_R, 0, STEREO_DFT_BAND_MAX ); - *nb_bits = 0; - k_offset = STEREO_DFT_OFFSET; + pSideGain = hStereoDft->side_gain_fx + k_offset * STEREO_DFT_BAND_MAX; // Q31 + pgIpd = hStereoDft->gipd_fx + k_offset; // Q13 + pPredGain = hStereoDft->res_pred_gain_fx + k_offset * STEREO_DFT_BAND_MAX; // Q31 + // gain_IPD = EPSILON; + gain_IPD = 0; + move32(); + sum_energy_L = EPSILON_FX_M; /* Set the accumulations for the no IPD Calculation */ + move32(); + sum_energy_L_e = EPSILON_FX_E; /* Set the accumulations for the no IPD Calculation */ + move16(); + sum_energy_R = EPSILON_FX_M; + move32(); + sum_energy_R_e = EPSILON_FX_E; + move16(); + sum_dot_prod_real = EPSILON_FX_M; + move32(); + sum_dot_prod_real_e = EPSILON_FX_E; + move16(); + sum_dot_prod_img = EPSILON_FX_M; + move32(); + sum_dot_prod_img_e = EPSILON_FX_E; + move16(); + sub_nrg_DMX2 = 0; + move32(); + sub_nrg_DMX2_e = 0; + move16(); - nbands_full = hStereoDft->nbands; + /*------------------------------------------------------------------* + * Band-wise processing + *-----------------------------------------------------------------*/ - if ( core_brate == FRAME_NO_DATA || core_brate == SID_2k40 ) - { - NFFT_inner = min( STEREO_DFT_N_32k_ENC, STEREO_DFT_N_MAX_ENC * inner_frame_tbl[hCPE->hCoreCoder[0]->bwidth] / L_FRAME48k ); - hStereoDft->band_res[k_offset] = hStereoDft->hConfig->band_res; - hStereoDft->res_pred_mode[k_offset] = 0; - hStereoDft->res_cod_mode[k_offset] = 0; - } - else + b2 = 0; + move16(); + FOR( b = 0; b < hStereoDft->nbands; b++ ) { - NFFT_inner = STEREO_DFT_N_MAX_ENC * inner_frame_tbl[hCPE->hCoreCoder[0]->bwidth] / L_FRAME48k; - } + pPredGain[b] = MAX_32; + move32(); + sum_nrg_L = EPSILON_FX_M; + move32(); + sum_nrg_L_e = EPSILON_FX_E; + move16(); + sum_nrg_R = EPSILON_FX_M; + move32(); + sum_nrg_R_e = EPSILON_FX_E; + move16(); + dot_prod_real = EPSILON_FX_M; + move32(); + dot_prod_real_e = EPSILON_FX_E; + move16(); + dot_prod_img = EPSILON_FX_M; + move32(); + dot_prod_img_e = EPSILON_FX_E; + move16(); + sum_past_nrgL = 0; + move32(); + sum_past_nrgL_e = 0; + move16(); + sum_past_nrgR = 0; + move32(); + sum_past_nrgR_e = 0; + move16(); + sum_past_dpr = 0; + move32(); + sum_past_dpr_e = 0; + move16(); + sum_past_dpi = 0; + move32(); + sum_past_dpi_e = 0; + move16(); - /* set number of bands according to bandwidth after BWD */ -#ifndef IVAS_FLOAT_FIXED - hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, ENC ); -#else - hStereoDft->nbands = stereo_dft_band_config_fx( hStereoDft->band_limits, hStereoDft->band_res[k_offset], NFFT_inner, ENC ); -#endif + WHILE( LT_16( hStereoDft->band_limits_dmx[b2], hStereoDft->band_limits[b + 1] ) ) + { + pDFT_L = DFT_L_fx; + // DFT_L_e = hStereoDft->DFT_fx_e[0]; + pDFT_R = DFT_R_fx; + // DFT_R_e = hStereoDft->DFT_fx_e[1]; + pNrgL = bin_nrgL_fx; + pNrgL_e = bin_nrgL_fx_e; + pNrgR = bin_nrgR_fx; + pNrgR_e = bin_nrgR_fx_e; - if ( core_brate == FRAME_NO_DATA ) - { - /* No data frame */ - ( *nb_bits ) = 0; - return; - } + sum_nrg_L2 = EPSILON_FX_M; + move32(); + sum_nrg_L2_e = EPSILON_FX_E; + move16(); + sum_nrg_R2 = EPSILON_FX_M; + move32(); + sum_nrg_R2_e = EPSILON_FX_E; + move16(); + dot_prod_real2 = EPSILON_FX_M; + move32(); + dot_prod_real2_e = EPSILON_FX_E; + move16(); + dot_prod_img2 = EPSILON_FX_M; + move32(); + dot_prod_img2_e = EPSILON_FX_E; + move16(); - /* attack present */ - /* attackPresent not sent in inactive frames, receiver assumes = 0 */ - if ( core_brate != SID_2k40 ) - { - push_indice( hBstr, IND_STEREO_DFT_ATTACK_PRESENT, hStereoDft->attackPresent, 1 ); - ( *nb_bits )++; - } + FOR( i = hStereoDft->band_limits_dmx[b2]; i < hStereoDft->band_limits_dmx[b2 + 1]; i++ ) + { + // sum_nrg_L2 += pNrgL[i]; + sum_nrg_L2 = BASOP_Util_Add_Mant32Exp( sum_nrg_L2, sum_nrg_L2_e, pNrgL[i], pNrgL_e[i], &sum_nrg_L2_e ); + // sum_nrg_R2 += pNrgR[i]; + sum_nrg_R2 = BASOP_Util_Add_Mant32Exp( sum_nrg_R2, sum_nrg_R2_e, pNrgR[i], pNrgR_e[i], &sum_nrg_R2_e ); - /* Writing coding residual coding mode into bitstream */ - if ( hStereoDft->hConfig->ada_wb_res_cod_mode && hCPE->hCoreCoder[0]->bwidth == WB ) - { - push_indice( hBstr, IND_STEREO_DFT_RES_COD, hStereoDft->res_cod_mode[k_offset], 1 ); - ( *nb_bits )++; - hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->hConfig->band_res][hStereoDft->res_cod_mode[k_offset]]; - hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); - } + /* compute dot product*/ + // dot_prod_real2 += pDFT_L[2 * i] * pDFT_R[2 * i] + pDFT_L[2 * i + 1] * pDFT_R[2 * i + 1]; + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i] ), add( DFT_L_fx_e[2 * i], DFT_R_fx_e[2 * i] ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i + 1] ), add( DFT_L_fx_e[2 * i + 1], DFT_R_fx_e[2 * i + 1] ), &L_tmp_e ); + dot_prod_real2 = BASOP_Util_Add_Mant32Exp( dot_prod_real2, dot_prod_real2_e, L_tmp, L_tmp_e, &dot_prod_real2_e ); + // dot_prod_img2 += pDFT_L[2 * i + 1] * pDFT_R[2 * i] - pDFT_L[2 * i] * pDFT_R[2 * i + 1]; + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i] ), add( DFT_L_fx_e[2 * i + 1], DFT_R_fx_e[2 * i] ), L_negate( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i + 1] ) ), add( DFT_L_fx_e[2 * i], DFT_R_fx_e[2 * i + 1] ), &L_tmp_e ); + dot_prod_img2 = BASOP_Util_Add_Mant32Exp( dot_prod_img2, dot_prod_img2_e, L_tmp, L_tmp_e, &dot_prod_img2_e ); + } + // abs_L_R2 = sqrtf(dot_prod_real2 * dot_prod_real2 + dot_prod_img2 * dot_prod_img2); + abs_L_R2 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( dot_prod_real2, dot_prod_real2 ), shl( dot_prod_real2_e, 1 ), Mpy_32_32( dot_prod_img2, dot_prod_img2 ), shl( dot_prod_img2_e, 1 ), &abs_L_R2_e ); + abs_L_R2 = Sqrt32( abs_L_R2, &abs_L_R2_e ); + // sub_nrg_DMX2 = sum_nrg_L2 + sum_nrg_R2 + 2 * abs_L_R2; + L_tmp = BASOP_Util_Add_Mant32Exp( sum_nrg_L2, sum_nrg_L2_e, sum_nrg_R2, sum_nrg_R2_e, &L_tmp_e ); + sub_nrg_DMX2 = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_e, abs_L_R2, add( abs_L_R2_e, 1 ), &sub_nrg_DMX2_e ); + + IF( LT_16( b2, hStereoDft->gipd_band_max ) ) + { + // hStereoDft->dot_prod_real_smooth[b2] = 0.5f * hStereoDft->dot_prod_real_smooth[b2] + 0.5f * dot_prod_real2; + hStereoDft->dot_prod_real_smooth_fx[b2] = BASOP_Util_Add_Mant32Exp( hStereoDft->dot_prod_real_smooth_fx[b2], sub( hStereoDft->dot_prod_real_smooth_fx_e[b2], 1 ), dot_prod_real2, sub( dot_prod_real2_e, 1 ), &hStereoDft->dot_prod_real_smooth_fx_e[b2] ); + move32(); + // hStereoDft->dot_prod_img_smooth[b2] = 0.5f * hStereoDft->dot_prod_img_smooth[b2] + 0.5f * dot_prod_img2; + hStereoDft->dot_prod_img_smooth_fx[b2] = BASOP_Util_Add_Mant32Exp( hStereoDft->dot_prod_img_smooth_fx[b2], sub( hStereoDft->dot_prod_img_smooth_fx_e[b2], 1 ), dot_prod_img2, sub( dot_prod_img2_e, 1 ), &hStereoDft->dot_prod_img_smooth_fx_e[b2] ); + move32(); + // pIpd[b2] = (float) atan2f( hStereoDft->dot_prod_img_smooth[b2], hStereoDft->dot_prod_real_smooth[b2] ); + pIpd[b2] = BASOP_util_atan2( hStereoDft->dot_prod_img_smooth_fx[b2], hStereoDft->dot_prod_real_smooth_fx[b2], sub( hStereoDft->dot_prod_img_smooth_fx_e[b2], hStereoDft->dot_prod_real_smooth_fx_e[b2] ) ); // Q13 + move32(); + + ipd_smooth[b2] = stereo_dft_calc_mean_bipd_fx( &pIpd[b2], hStereoDft->ipd_buf_fx[b2] ); + move32(); + + // gain_IPD += ( sum_nrg_L2 + sum_nrg_R2 + 2 * dot_prod_real2 ) / sub_nrg_DMX2 / hStereoDft->gipd_band_max; + L_tmp1 = BASOP_Util_Add_Mant32Exp( sum_nrg_L2, sum_nrg_L2_e, sum_nrg_R2, sum_nrg_R2_e, &L_tmp1_e ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, L_tmp1_e, dot_prod_real2, add( dot_prod_real2_e, 1 ), &L_tmp1_e ); + W_tmp = W_mult_32_32( sub_nrg_DMX2, hStereoDft->gipd_band_max ); + W_shift = W_norm( W_tmp ); + L_tmp2 = W_extract_h( W_shl( W_tmp, W_shift ) ); + L_tmp2_e = sub( add( sub_nrg_DMX2_e, 31 ), W_shift ); + L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ); + L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); + L_tmp = L_shl( L_tmp, L_tmp_e ); // Q31hStereoDft->gainIPD_sm_fx = L_add( L_shr( hStereoDft->gainIPD_sm_fx, 1 ), L_ + gain_IPD = L_add_sat( gain_IPD, L_tmp ); // Q31: saturation expected + } + sum_past_nrgL2 = EPSILON_FX_M; + move32(); + sum_past_nrgL2_e = EPSILON_FX_E; + move16(); + sum_past_nrgR2 = EPSILON_FX_M; + move32(); + sum_past_nrgR2_e = EPSILON_FX_E; + move16(); + sum_past_dpr2 = EPSILON_FX_M; + move32(); + sum_past_dpr2_e = EPSILON_FX_E; + move16(); + sum_past_dpi2 = EPSILON_FX_M; + move32(); + sum_past_dpi2_e = EPSILON_FX_E; + move16(); + test(); + test(); + test(); + IF( ( EQ_16( hStereoDft->band_res[k_offset], STEREO_DFT_BAND_RES_HIGH ) && LT_16( b2, STEREO_DFT_NRG_PAST_MAX_BAND ) ) || + ( EQ_16( hStereoDft->band_res[k_offset], STEREO_DFT_BAND_RES_LOW ) && LT_16( b2, 2 * STEREO_DFT_NRG_PAST_MAX_BAND_LB ) ) ) + { + hStereoDft->past_nrgL_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = sum_nrg_L2; + move32(); + hStereoDft->past_nrgL_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = sum_nrg_L2_e; + move16(); + hStereoDft->past_nrgR_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = sum_nrg_R2; + move32(); + hStereoDft->past_nrgR_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = sum_nrg_R2_e; + move16(); + hStereoDft->past_dot_prod_real_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = dot_prod_real2; + move32(); + hStereoDft->past_dot_prod_real_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = dot_prod_real2_e; + move16(); + hStereoDft->past_dot_prod_imag_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = dot_prod_img2; + move32(); + hStereoDft->past_dot_prod_imag_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = dot_prod_img2_e; + move16(); + + FOR( i = 0; i < STEREO_DFT_NRG_PAST_LEN; i++ ) + { + // sum_past_nrgL2 += hStereoDft->past_nrgL[b2 * STEREO_DFT_NRG_PAST_LEN + i]; + sum_past_nrgL2 = BASOP_Util_Add_Mant32Exp( sum_past_nrgL2, sum_past_nrgL2_e, hStereoDft->past_nrgL_fx[b2 * STEREO_DFT_NRG_PAST_LEN + i], hStereoDft->past_nrgL_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + i], &sum_past_nrgL2_e ); + // sum_past_nrgR2 += hStereoDft->past_nrgR[b2 * STEREO_DFT_NRG_PAST_LEN + i]; + sum_past_nrgR2 = BASOP_Util_Add_Mant32Exp( sum_past_nrgR2, sum_past_nrgR2_e, hStereoDft->past_nrgR_fx[b2 * STEREO_DFT_NRG_PAST_LEN + i], hStereoDft->past_nrgR_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + i], &sum_past_nrgR2_e ); + // sum_past_dpr2 += hStereoDft->past_dot_prod_real[b2 * STEREO_DFT_NRG_PAST_LEN + i]; + sum_past_dpr2 = BASOP_Util_Add_Mant32Exp( sum_past_dpr2, sum_past_dpr2_e, hStereoDft->past_dot_prod_real_fx[b2 * STEREO_DFT_NRG_PAST_LEN + i], hStereoDft->past_dot_prod_real_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + i], &sum_past_dpr2_e ); + // sum_past_dpi2 += hStereoDft->past_dot_prod_imag[b2 * STEREO_DFT_NRG_PAST_LEN + i]; + sum_past_dpi2 = BASOP_Util_Add_Mant32Exp( sum_past_dpi2, sum_past_dpi2_e, hStereoDft->past_dot_prod_imag_fx[b2 * STEREO_DFT_NRG_PAST_LEN + i], hStereoDft->past_dot_prod_imag_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + i], &sum_past_dpi2_e ); + } - if ( nbands_full < hStereoDft->nbands ) - { - hStereoDft->reverb_flag = 0; - } + IF( hStereoDft->attackPresent ) + { + /* omit transient frames from past part of parameter estimation in following frames */ + Word16 prev_pos = add( pos, STEREO_DFT_NRG_PAST_LEN - 1 ) % STEREO_DFT_NRG_PAST_LEN; + hStereoDft->past_nrgL_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_nrgL_fx[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move32(); + hStereoDft->past_nrgL_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_nrgL_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move16(); + hStereoDft->past_nrgR_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_nrgR_fx[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move32(); + hStereoDft->past_nrgR_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_nrgR_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move16(); + hStereoDft->past_dot_prod_real_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_dot_prod_real_fx[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move32(); + hStereoDft->past_dot_prod_real_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_dot_prod_real_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move16(); + hStereoDft->past_dot_prod_imag_fx[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_dot_prod_imag_fx[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move32(); + hStereoDft->past_dot_prod_imag_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + pos] = hStereoDft->past_dot_prod_imag_fx_e[b2 * STEREO_DFT_NRG_PAST_LEN + prev_pos]; + move16(); + } - /* Side gains */ - hStereoDft->side_gain_flag_1 = 0; /* EC coding by default */ - side_gain_mode_decision( hStereoDft, encoded_ind_GR, sp_aud_decision0, hCPE->hCoreCoder[0]->last_core_brate ); + // sum_past_dot_prod_abs2 = sqrtf( sum_past_dpr2 * sum_past_dpr2 + sum_past_dpi2 * sum_past_dpi2 ); + sum_past_dot_prod_abs2 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( sum_past_dpr2, sum_past_dpr2 ), shl( sum_past_dpr2_e, 1 ), Mpy_32_32( sum_past_dpi2, sum_past_dpi2 ), shl( sum_past_dpi2_e, 1 ), &sum_past_dot_prod_abs2_e ); + sum_past_dot_prod_abs2 = Sqrt32( sum_past_dot_prod_abs2, &sum_past_dot_prod_abs2_e ); + // dot_prod_nrg_ratio[b2] = sum_past_dot_prod_abs2 / ( sum_past_nrgL2 + sum_past_nrgR2 + EPSILON ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( sum_past_nrgL2, sum_past_nrgL2_e, sum_past_nrgR2, sum_past_nrgR2_e, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); + dot_prod_nrg_ratio_fx[b2] = BASOP_Util_Divide3232_Scale_cadence( sum_past_dot_prod_abs2, L_tmp2, &L_tmp_e ); + move32(); + L_tmp_e = add( L_tmp_e, sub( sum_past_dot_prod_abs2_e, L_tmp2_e ) ); + dot_prod_nrg_ratio_fx[b2] = L_shl( dot_prod_nrg_ratio_fx[b2], L_tmp_e ); // Q31 + move32(); + dot_prod_nrg_ratio_fx_e[b2] = 0; + move16(); + // printf("\n%f\t", (float)dot_prod_nrg_ratio_fx[b2] / 0x7fffffff); + } + ELSE + { + // sum_past_nrgL2 += sum_nrg_L2; + sum_past_nrgL2 = BASOP_Util_Add_Mant32Exp( sum_past_nrgL2, sum_past_nrgL2_e, sum_nrg_L2, sum_nrg_L2_e, &sum_past_nrgL2_e ); + // sum_past_nrgR2 += sum_nrg_R2; + sum_past_nrgR2 = BASOP_Util_Add_Mant32Exp( sum_past_nrgR2, sum_past_nrgR2_e, sum_nrg_R2, sum_nrg_R2_e, &sum_past_nrgR2_e ); + // dot_prod_nrg_ratio[b2] = sqrtf( dot_prod_real2 * dot_prod_real2 + dot_prod_img2 * dot_prod_img2 ); + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( dot_prod_real2, dot_prod_real2 ), shl( dot_prod_real2_e, 1 ), Mpy_32_32( dot_prod_img2, dot_prod_img2 ), shl( dot_prod_img2_e, 1 ), &L_tmp_e ); + L_tmp = Sqrt32( L_tmp, &L_tmp_e ); + dot_prod_nrg_ratio_fx[b2] = L_tmp; + move32(); + dot_prod_nrg_ratio_fx_e[b2] = L_tmp_e; + move16(); + IF( EQ_16( b2, 2 * STEREO_DFT_NRG_PAST_MAX_BAND_LB ) ) /* hStereoDft->band_res[k_offset] == 2 */ + { + // dot_prod_nrg_ratio[b2] /= ( sum_nrg_L2 + sum_nrg_R2 + EPSILON ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( sum_nrg_L2, sum_nrg_L2_e, sum_nrg_R2, sum_nrg_R2_e, &L_tmp2_e ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( L_tmp2, L_tmp2_e, EPSILON_FX_M, EPSILON_FX_E, &L_tmp2_e ); + dot_prod_nrg_ratio_fx[b2] = BASOP_Util_Divide3232_Scale_cadence( dot_prod_nrg_ratio_fx[b2], L_tmp2, &L_tmp_e ); + move32(); + L_tmp_e = add( L_tmp_e, sub( dot_prod_nrg_ratio_fx_e[b2], L_tmp2_e ) ); + dot_prod_nrg_ratio_fx[b2] = L_shl( dot_prod_nrg_ratio_fx[b2], L_tmp_e ); // Q31 + move32(); + dot_prod_nrg_ratio_fx_e[b2] = 0; + move16(); + } + } + // sum_nrg_L += sum_nrg_L2; + sum_nrg_L = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, sum_nrg_L2, sum_nrg_L2_e, &sum_nrg_L_e ); + // sum_nrg_R += sum_nrg_R2; + sum_nrg_R = BASOP_Util_Add_Mant32Exp( sum_nrg_R, sum_nrg_R_e, sum_nrg_R2, sum_nrg_R2_e, &sum_nrg_R_e ); + // dot_prod_real += dot_prod_real2; + dot_prod_real = BASOP_Util_Add_Mant32Exp( dot_prod_real, dot_prod_real_e, dot_prod_real2, dot_prod_real2_e, &dot_prod_real_e ); + // dot_prod_img += dot_prod_img2; + dot_prod_img = BASOP_Util_Add_Mant32Exp( dot_prod_img, dot_prod_img_e, dot_prod_img2, dot_prod_img2_e, &dot_prod_img_e ); + + // sum_past_nrgL += sum_past_nrgL2; + sum_past_nrgL = BASOP_Util_Add_Mant32Exp( sum_past_nrgL, sum_past_nrgL_e, sum_past_nrgL2, sum_past_nrgL2_e, &sum_past_nrgL_e ); + // sum_past_nrgR += sum_past_nrgR2; + sum_past_nrgR = BASOP_Util_Add_Mant32Exp( sum_past_nrgR, sum_past_nrgR_e, sum_past_nrgR2, sum_past_nrgR2_e, &sum_past_nrgR_e ); + // sum_past_dpr += sum_past_dpr2; + sum_past_dpr = BASOP_Util_Add_Mant32Exp( sum_past_dpr, sum_past_dpr_e, sum_past_dpr2, sum_past_dpr2_e, &sum_past_dpr_e ); + // sum_past_dpi += sum_past_dpi2; + sum_past_dpi = BASOP_Util_Add_Mant32Exp( sum_past_dpi, sum_past_dpi_e, sum_past_dpi2, sum_past_dpi2_e, &sum_past_dpi_e ); - /* residual pred. gains */ - hStereoDft->res_pred_flag_1 = 0; /* EC coding by default */ + b2++; + } + // sum_energy_L += sum_nrg_L; /* Energies of the individual Band for Left and Right */ + sum_energy_L = BASOP_Util_Add_Mant32Exp( sum_energy_L, sum_energy_L_e, sum_nrg_L, sum_nrg_L_e, &sum_energy_L_e ); /* Energies of the individual Band for Left and Right */ + // sum_energy_R += sum_nrg_R; + sum_energy_R = BASOP_Util_Add_Mant32Exp( sum_energy_R, sum_energy_R_e, sum_nrg_R, sum_nrg_R_e, &sum_energy_R_e ); + // sum_dot_prod_real += dot_prod_real; + sum_dot_prod_real = BASOP_Util_Add_Mant32Exp( sum_dot_prod_real, sum_dot_prod_real_e, dot_prod_real, dot_prod_real_e, &sum_dot_prod_real_e ); + // sum_dot_prod_img += dot_prod_img; + sum_dot_prod_img = BASOP_Util_Add_Mant32Exp( sum_dot_prod_img, sum_dot_prod_img_e, dot_prod_img, dot_prod_img_e, &sum_dot_prod_img_e ); - res_pred_gain_mode_decision( hStereoDft, encoded_ind_pred_GR, k_offset, hCPE->hCoreCoder[0]->last_core_brate ); + /* compute side and residual gains over two frames */ + // abs_L_R = sqrtf( dot_prod_real * dot_prod_real + dot_prod_img * dot_prod_img ); + abs_L_R = BASOP_Util_Add_Mant32Exp( Mpy_32_32( dot_prod_real, dot_prod_real ), shl( dot_prod_real_e, 1 ), Mpy_32_32( dot_prod_img, dot_prod_img ), shl( dot_prod_img_e, 1 ), &abs_L_R_e ); + abs_L_R = Sqrt32( abs_L_R, &abs_L_R_e ); - /*------------------------------------------------------------------* - * write ITD indices - *-----------------------------------------------------------------*/ + test(); + test(); + IF( EQ_16( hStereoDft->band_res[k_offset], STEREO_DFT_BAND_RES_LOW ) && LT_16( b, 4 ) ) + { + // sum_past_dot_prod_abs = sqrtf( sum_past_dpr * sum_past_dpr + sum_past_dpi * sum_past_dpi ); + sum_past_dot_prod_abs = BASOP_Util_Add_Mant32Exp( Mpy_32_32( sum_past_dpr, sum_past_dpr ), shl( sum_past_dpr_e, 1 ), Mpy_32_32( sum_past_dpi, sum_past_dpi ), shl( sum_past_dpi_e, 1 ), &sum_past_dot_prod_abs_e ); + sum_past_dot_prod_abs = Sqrt32( sum_past_dot_prod_abs, &sum_past_dot_prod_abs_e ); + } + ELSE IF( EQ_16( hStereoDft->band_res[k_offset], STEREO_DFT_BAND_RES_HIGH ) && LT_16( b, 9 ) ) + { + sum_past_dot_prod_abs = sum_past_dot_prod_abs2; + move32(); + sum_past_dot_prod_abs_e = sum_past_dot_prod_abs2_e; + move16(); + } + ELSE + { + sum_past_dot_prod_abs = abs_L_R; + move32(); + sum_past_dot_prod_abs_e = abs_L_R_e; + move16(); + } - if ( core_brate != SID_2k40 ) - { - push_indice( hBstr, IND_STEREO_DFT_ITD_MODE, ( hStereoDft->hItd->itd[k_offset] != 0 ), STEREO_DFT_ITD_MODE_NBITS ); - ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ - } + // c = sqrtf( sum_past_nrgL / sum_past_nrgR ); + c = BASOP_Util_Divide3232_Scale_cadence( sum_past_nrgL, sum_past_nrgR, &c_e ); + c_e = add( c_e, sub( sum_past_nrgL_e, sum_past_nrgR_e ) ); + c = Sqrt32( c, &c_e ); + // sum_past_nrg_dmx = sum_past_nrgL + sum_past_nrgR + 2 * sum_past_dot_prod_abs; + sum_past_nrg_dmx = BASOP_Util_Add_Mant32Exp( sum_past_nrgL, sum_past_nrgL_e, sum_past_nrgR, sum_past_nrgR_e, &sum_past_nrg_dmx_e ); + sum_past_nrg_dmx = BASOP_Util_Add_Mant32Exp( sum_past_nrg_dmx, sum_past_nrg_dmx_e, sum_past_dot_prod_abs, add( sum_past_dot_prod_abs_e, 1 ), &sum_past_nrg_dmx_e ); + // sub_nrg_DMX[b] = sum_nrg_L + sum_nrg_R + 2 * abs_L_R; + sub_nrg_DMX[b] = BASOP_Util_Add_Mant32Exp( sum_nrg_L, sum_nrg_L_e, sum_nrg_R, sum_nrg_R_e, &sub_nrg_DMX_e[b] ); + move32(); + sub_nrg_DMX[b] = BASOP_Util_Add_Mant32Exp( sub_nrg_DMX[b], sub_nrg_DMX_e[b], abs_L_R, add( abs_L_R_e, 1 ), &sub_nrg_DMX_e[b] ); + move32(); - if ( core_brate != SID_2k40 ) - { - if ( hStereoDft->hItd->itd[k_offset] ) + sub_nrg_L[b] = sum_nrg_L; + move32(); + sub_nrg_L_e[b] = sum_nrg_L_e; + move16(); + sub_nrg_R[b] = sum_nrg_R; + move32(); + sub_nrg_R_e[b] = sum_nrg_R_e; + move16(); + + test(); + test(); + IF( ( hStereoDft->res_pred_mode[k_offset] && GE_16( b, hStereoDft->res_pred_band_min ) ) || LT_16( b, hStereoDft->res_cod_band_max ) ) { - itd = hStereoDft->hItd->itd_index[k_offset]; - if ( itd > 255 ) + // g = ( sum_past_nrgL - sum_past_nrgR ) / ( sum_past_nrg_dmx ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( sum_past_nrgL, sum_past_nrgL_e, L_negate( sum_past_nrgR ), sum_past_nrgR_e, &L_tmp1_e ); + L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, sum_past_nrg_dmx, &L_tmp_e ); + L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, sum_past_nrg_dmx_e ) ); + g = L_shl_sat( L_tmp, L_tmp_e ); // Q31 saturation expected + pSideGain[b] = g; + move32(); + } + ELSE + { + g = 0; /* to avoid compilation warning */ + move32(); + // pSideGain[b] = ( c - 1 ) / ( c + 1 ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( c, c_e, MIN_32, 0, &L_tmp1_e ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( c, c_e, MAX_32, 0, &L_tmp2_e ); + L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ); + L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); + pSideGain[b] = L_shl_sat( L_tmp, L_tmp_e ); // Q31 saturation expected + move32(); + } + + test(); + test(); + IF( hStereoDft->res_pred_mode[k_offset] && GE_16( b, hStereoDft->res_pred_band_min ) && !( hStereoDft->attackPresent ) ) + { + /*(1-g)^2*L*L' + (1+g)^2*R*R' - 2(1-g^2)*abs(L*R')*/ + // pPredGain[b] = max( 0, ( ( 1 - g ) * sum_past_nrgL + ( 1 + g ) * sum_past_nrgR - 2 * sum_past_dot_prod_abs ) ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( MAX_32, 0, L_negate( g ), 0, &L_tmp1_e ); + L_tmp1 = Mpy_32_32( L_tmp1, sum_past_nrgL ); + L_tmp1_e = add( L_tmp1_e, sum_past_nrgL_e ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( MAX_32, 0, g, 0, &L_tmp2_e ); + L_tmp2 = Mpy_32_32( L_tmp2, sum_past_nrgR ); + L_tmp2_e = add( L_tmp2_e, sum_past_nrgR_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp1, L_tmp1_e, L_tmp2, L_tmp2_e, &L_tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_e, L_negate( sum_past_dot_prod_abs ), add( sum_past_dot_prod_abs_e, 1 ), &L_tmp_e ); + IF( L_tmp < 0 ) { - itd -= 256; + L_tmp = 0; + move32(); + L_tmp_e = 0; + move16(); + } - if ( itd < 20 ) + /*Normalized with energy of DMX*/ + + /*Regularized gain computation by adding a coherent low energy contribution->avoid singularity for very low energy signals */ + + // reg = ( hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b] ) * sqrtf( STEREO_DFT_N_32k_ENC ); + reg = L_mult0( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), 18318 /* sqrtf( STEREO_DFT_N_32k_ENC ) in Q9 */ ); + reg_e = norm_l( reg ); + reg = L_shl( reg, reg_e ); + reg_e = sub( 22, reg_e ); + // reg *= reg; + reg = Mpy_32_32( reg, reg ); + reg_e = shl( reg_e, 1 ); + + // pPredGain[b] = sqrtf( pPredGain[b] / ( reg + sum_past_nrg_dmx ) ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( reg, reg_e, sum_past_nrg_dmx, sum_past_nrg_dmx_e, &L_tmp2_e ); + L_tmp1 = BASOP_Util_Divide3232_Scale_cadence( L_tmp, L_tmp2, &L_tmp1_e ); + L_tmp1_e = add( L_tmp1_e, sub( L_tmp_e, L_tmp2_e ) ); + L_tmp1 = Sqrt32( L_tmp1, &L_tmp1_e ); + pPredGain[b] = L_shl( L_tmp1, L_tmp1_e ); // Q31 + move32(); + + IF( hStereoDft->hItd->deltaItd_fx[k_offset] != 0 ) + { + Word32 gain_offset, conversion_factor /*Q30*/; + Word16 dItd32; + + /* factor for converting deltaItd to 32kHz */ + conversion_factor = ONE_IN_Q30 /*1.f*/; + move32(); + IF( EQ_16( hStereoDft->NFFT, STEREO_DFT_N_16k_ENC ) ) { - push_indice( hBstr, IND_STEREO_DFT_ITD_HUFF, 1, 1 ); /* use Huffman*/ - push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 1, 1 ); /* negative */ - push_indice( hBstr, IND_STEREO_DFT_ITD_COD, dft_code_itd[itd], dft_len_itd[itd] ); - ( *nb_bits ) += dft_len_itd[itd] + 2; + conversion_factor = MAX_32 /*2.f*/; + move32(); } - else + ELSE IF( EQ_16( hStereoDft->NFFT, STEREO_DFT_N_MAX_ENC ) ) { - push_indice( hBstr, IND_STEREO_DFT_ITD_HUFF, 0, 1 ); /* don't use Huffman */ - push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 1, 1 ); /* negative */ - push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_ITD_NBITS - 1 ); - ( *nb_bits ) += STEREO_DFT_ITD_NBITS + 1; + conversion_factor = 715827883 /*2.f / 3*/; + move32(); } + // dItd32 = (int16_t) floorf( conversion_factor * hStereoDft->hItd->deltaItd[k_offset] + 0.5f ); + dItd32 = (Word16) L_shr_r( Mpy_32_32( conversion_factor, hStereoDft->hItd->deltaItd_fx[k_offset] ), Q15 ); // Q0 + + gain_offset = stereo_dft_gain_offset_fx( c, c_e, dItd32 ); // Q31 + pPredGain[b] = L_max( 0, L_sub( pPredGain[b], gain_offset ) ); + move32(); } - else + + /*Limiter for active speech*/ + test(); + IF( sp_aud_decision0 == 0 && vad_flag ) { - if ( itd < 20 ) - { - push_indice( hBstr, IND_STEREO_DFT_ITD_HUFF, 1, 1 ); /* use Huffman*/ - push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 0, 1 ); /* positive */ - push_indice( hBstr, IND_STEREO_DFT_ITD_COD, dft_code_itd[itd], dft_len_itd[itd] ); - ( *nb_bits ) += dft_len_itd[itd] + 2; - } - else + /*Avoid jump of residual prediction gain when ITD is changing*/ + IF( NE_32( hStereoDft->hItd->deltaItd_fx[k_offset], hStereoDft->hItd->deltaItd_fx[0] ) ) { - /* don't use Huffman and positive*/ - push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_ITD_NBITS + 1 ); - ( *nb_bits ) += STEREO_DFT_ITD_NBITS + 1; + pPredGain[b] = L_min( hStereoDft->res_pred_gain_f_fx[b], pPredGain[b] ); + move32(); } + + /*Limiter*/ + // hStereoDft->res_pred_gain_f[b] = 0.9f * hStereoDft->res_pred_gain_f[b] + 0.1f * pPredGain[b]; + hStereoDft->res_pred_gain_f_fx[b] = L_add( Mpy_32_32( 1932735283 /* 0.9f in Q31*/, hStereoDft->res_pred_gain_f_fx[b] ), Mpy_32_32( 214748365 /* 0.1f in Q31*/, pPredGain[b] ) ); + move32(); + // pPredGain[b] = min( 1.1f * hStereoDft->res_pred_gain_f[b], pPredGain[b] ); + pPredGain[b] = L_shl( L_min( Mpy_32_32( 1181116006 /*1.1f in Q30*/, hStereoDft->res_pred_gain_f_fx[b] ), L_shr( pPredGain[b], 1 ) ), 1 ); + move32(); + } + ELSE + { + hStereoDft->res_pred_gain_f_fx[b] = pPredGain[b]; + move32(); } } + ELSE + { + pPredGain[b] = 0; + move32(); + } + + + IF( EQ_16( b2, hStereoDft->gipd_band_max ) ) + { + ipd_mean_change = stereo_dft_calc_mean_ipd_change_fx( pIpd, ipd_smooth, hStereoDft->gipd_band_max ); // Q13 + // hStereoDft->sum_dot_prod_real = ( 1.f - hStereoDft->sfm ) * hStereoDft->sum_dot_prod_real + hStereoDft->sfm * sum_dot_prod_real; + hStereoDft->sum_dot_prod_real_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( L_sub( MAX_32, hStereoDft->sfm_fx ), hStereoDft->sum_dot_prod_real_fx ), hStereoDft->sum_dot_prod_real_fx_e, + Mpy_32_32( hStereoDft->sfm_fx, sum_dot_prod_real ), sum_dot_prod_real_e, &hStereoDft->sum_dot_prod_real_fx_e ); + move32(); + // hStereoDft->sum_dot_prod_img = ( 1.f - hStereoDft->sfm ) * hStereoDft->sum_dot_prod_img + hStereoDft->sfm * sum_dot_prod_img; + hStereoDft->sum_dot_prod_img_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( L_sub( MAX_32, hStereoDft->sfm_fx ), hStereoDft->sum_dot_prod_img_fx ), hStereoDft->sum_dot_prod_img_fx_e, + Mpy_32_32( hStereoDft->sfm_fx, sum_dot_prod_img ), sum_dot_prod_img_e, &hStereoDft->sum_dot_prod_img_fx_e ); + move32(); + + // pgIpd[0] = (float) atan2f( hStereoDft->sum_dot_prod_img, hStereoDft->sum_dot_prod_real ); + pgIpd[0] = BASOP_util_atan2( hStereoDft->sum_dot_prod_img_fx, hStereoDft->sum_dot_prod_real_fx, sub( hStereoDft->sum_dot_prod_img_fx_e, hStereoDft->sum_dot_prod_real_fx_e ) ); // Q13 + move32(); + + stereo_dft_gipd_stabilization_fx( &pgIpd[0], hStereoDft->prev_gipd_fx, ipd_mean_change ); + hStereoDft->prev_gipd_fx = pgIpd[0]; + move32(); + } } + hStereoDft->nrg_past_pos = ( pos + 1 ) % STEREO_DFT_NRG_PAST_LEN; + move16(); -#ifdef DEBUG_MODE_DFT_BITS - fprintf( ITD_bits, "%d ", *nb_bits ); -#endif /*------------------------------------------------------------------* - * write Side gain indices + * Compute IPDs *-----------------------------------------------------------------*/ - /* Side Gain flag 1 */ - nb = 0; - if ( hStereoDft->side_gain_flag_1 > 0 ) + stereo_dft_enc_get_nipd_flag_fx( hStereoDft, sp_aud_decision0, gain_IPD ); + + IF( flag_quant ) { - push_indice( hBstr, IND_STEREO_DFT_SIDEGAIN_FLAG, hStereoDft->side_gain_flag_1, 2 ); - nb += 2; + IF( hStereoDft->no_ipd_flag == 0 ) + { + hStereoDft->sid_gipd_fx = *pgIpd; + move32(); + stereo_dft_quantize_ipd_fx( pgIpd, pgIpd, &( hStereoDft->gipd_index ), STEREO_DFT_GIPD_NBITS ); + } + ELSE + { + pgIpd[0] = 0; + move32(); + } } - else + diff_ipd = L_sub( pgIpd[0], pgIpd[-1] ); + + IF( LT_32( diff_ipd, -EVS_PI_FX ) ) { - push_indice( hBstr, IND_STEREO_DFT_SIDEGAIN_FLAG, hStereoDft->side_gain_flag_1, STEREO_DFT_FLAG_BITS ); - nb += STEREO_DFT_FLAG_BITS; + pgIpd[0] = L_add( pgIpd[0], EVS_2PI_FX ); + move32(); } - - no_GR_ord = 3; - - if ( hStereoDft->side_gain_flag_1 == 0 ) + ELSE IF( GT_32( diff_ipd, EVS_PI_FX ) ) { - nb += write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, encoded_ind_GR, hStereoDft->nbands, hStereoDft->side_gain_flag_2, no_GR_ord ); + pgIpd[0] = L_sub( pgIpd[0], EVS_2PI_FX ); + move32(); } - else + + IF( !hStereoDft->attackPresent ) { - if ( hStereoDft->side_gain_flag_1 == 2 ) + IF( hStereoDft->wasTransient ) { - nb += write_bitstream_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, hStereoDft->side_gain_index_ECDiff, hStereoDft->nbands, hStereoDft->side_gain_flag_2 - no_GR_ord ); + // pgIpd[0] = 0.8f * pgIpd[0] + 0.2f * pgIpd[-1]; + pgIpd[0] = L_add( Mpy_32_32( 1717986918 /*0.8f in Q31*/, pgIpd[0] ), Mpy_32_32( 429496730 /*0.2f in Q31*/, pgIpd[-1] ) ); + move32(); } - else + ELSE { - for ( b = 0; b < hStereoDft->nbands; b++ ) - { - /*ILD*/ - push_indice( hBstr, IND_STEREO_DFT_SIDEGAINS, hStereoDft->side_gain_index_EC[b], STEREO_DFT_SIDEGAIN_NBITS ); - nb += STEREO_DFT_SIDEGAIN_NBITS; - } + // pgIpd[0] = 0.5f * pgIpd[0] + 0.5f * pgIpd[-1]; + pgIpd[0] = L_add( L_shr( pgIpd[0], 1 ), L_shr( pgIpd[-1], 1 ) ); + move32(); } } - /* nb bits are used for side gain*/ - ( *nb_bits ) += nb; -#ifdef DEBUG_MODE_DFT_BITS - fprintf( SG_bits, "%d ", nb ); -#endif - nb = 0; + // c = sqrtf( sum_energy_L / sum_energy_R ); + c = BASOP_Util_Divide3232_Scale_cadence( sum_energy_L, sum_energy_R, &c_e ); + c_e = add( c_e, sub( sum_energy_L_e, sum_energy_R_e ) ); + c = Sqrt32( c, &c_e ); - if ( core_brate == SID_2k40 ) + // g = fabsf( ( c - 1 ) / ( c + 1 ) ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( c, c_e, MIN_32, 0, &L_tmp1_e ); + L_tmp2 = BASOP_Util_Add_Mant32Exp( c, c_e, MAX_32, 0, &L_tmp2_e ); + g = L_abs( BASOP_Util_Divide3232_Scale_cadence( L_tmp1, L_tmp2, &L_tmp_e ) ); + L_tmp_e = add( L_tmp_e, sub( L_tmp1_e, L_tmp2_e ) ); + g = L_shl_sat( g, L_tmp_e ); // Q31 saturation expected + IF( GT_32( g, 1717986918 /*0.8f in Q31*/ ) ) { - stereo_dft_enc_sid_calc_coh( hStereoDft, hCPE->hStereoCng->prev_cohBand, &hCPE->hStereoCng->td_active, &hCPE->hStereoCng->first_SID, cohBand ); - - if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 ) ) + // g = max( 0.f, -10.f * g + 9.0f ); + g = L_max( 0, L_sub( 1932735283 /*9.f/10.f in Q31*/, g ) ); + W_tmp = W_mult0_32_32( g, 10 ); + if ( GT_64( W_tmp, MAX_32 ) ) { - if ( hStereoDft->hItd->itd[k_offset] != 0 ) - { - /* Re-quantize ITD with lower resolution for Stereo CNG */ - itd = hStereoDft->hItd->itd_index[k_offset]; - if ( itd > 255 ) - { - itd -= 256; - } - itd = itd >> STEREO_DFT_SID_ITD_FAC; + W_tmp = MAX_32; + move64(); + } + g = W_extract_l( W_tmp ); // Q31 + FOR( b = 0; b < hStereoDft->nbands; b++ ) + { + // pPredGain[b] *= g; + pPredGain[b] = Mpy_32_32( pPredGain[b], g ); + move32(); + } + } - sid_itd = itd && 1; - } - else - { - sid_itd = 0; - } + IF( EQ_16( hStereoDft->hConfig->band_res, STEREO_DFT_BAND_RES_LOW ) ) + { + hStereoDft->reverb_flag = 1; + move16(); + } + ELSE + { + stereo_dft_enc_get_reverb_flag_fx( hStereoDft, pPredGain, sub_nrg_DMX, sub_nrg_DMX_e, sub_nrg_L, sub_nrg_L_e, sub_nrg_R, sub_nrg_R_e, k_offset, bin_nrgL_fx, bin_nrgL_fx_e, bin_nrgR_fx, bin_nrgR_fx_e ); + } - push_indice( hBstr, IND_STEREO_DFT_ITD_MODE, sid_itd, STEREO_DFT_ITD_MODE_NBITS ); - ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ - if ( sid_itd ) - { - itd = hStereoDft->hItd->itd_index[k_offset]; - if ( itd > 255 ) - { - itd -= 256; - itd = itd >> STEREO_DFT_SID_ITD_FAC; + /*------------------------------------------------------------------* + * Compute Side gains + *-----------------------------------------------------------------*/ - if ( itd > ( ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1 ) ) - { - itd = ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1; - } + FOR( b = 0; b < hStereoDft->nbands; b++ ) + { + hStereoDft->sidSideGain_fx[b] = *( pSideGain + b ); + move32(); - push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 1, 1 ); /* negative */ - push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_SID_ITD_NBITS ); - ( *nb_bits ) += STEREO_DFT_SID_ITD_NBITS + 1; - } - else - { - itd = itd >> STEREO_DFT_SID_ITD_FAC; + /* Quantization */ + IF( flag_quant ) + { + stereo_dft_quantize_res_gains_fx( pSideGain + b, pPredGain + b, pSideGain + b, pPredGain + b, hStereoDft->side_gain_index_EC + b, hStereoDft->res_pred_index_EC + b ); + } - if ( itd > ( ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1 ) ) - { - itd = ( 1 << STEREO_DFT_SID_ITD_NBITS ) - 1; - } - push_indice( hBstr, IND_STEREO_DFT_ITD_NEG, 0, 1 ); /* Positive */ - push_indice( hBstr, IND_STEREO_DFT_ITD_COD, itd, STEREO_DFT_SID_ITD_NBITS ); - ( *nb_bits ) += STEREO_DFT_SID_ITD_NBITS + 1; - } + IF( !hStereoDft->attackPresent ) + { + IF( LT_16( b, hStereoDft->res_cod_band_max ) ) + { + // pSideGain[b] = dft_res_cod_alpha[b] * pSideGain[b] + ( 1 - dft_res_cod_alpha[b] ) * pSideGain[b - STEREO_DFT_BAND_MAX]; + pSideGain[b] = L_add( Mpy_32_16_1( pSideGain[b], dft_res_cod_alpha_fx[b] ), Mpy_32_16_1( pSideGain[b - STEREO_DFT_BAND_MAX], sub( MAX_16, dft_res_cod_alpha_fx[b] ) ) ); + move32(); } } } /*------------------------------------------------------------------* - * write IPD indices + * simulate prediction of parameters at the decoder *-----------------------------------------------------------------*/ - if ( core_brate != SID_2k40 ) + IF( hStereoDft->reverb_flag ) { - push_indice( hBstr, IND_STEREO_DFT_NO_IPD_FLAG, hStereoDft->no_ipd_flag, STEREO_DFT_FLAG_BITS ); - nb += STEREO_DFT_FLAG_BITS; /*IPD mode flag: 1bit*/ + Word16 ipred, bpred0, bpred1, max_dev, sum_abs_dev; - if ( hStereoDft->no_ipd_flag == 0 ) + ipred = 0; + move16(); + max_dev = 0; + move16(); + sum_abs_dev = 0; + move16(); + + /* parameters for bred0 <= b < bpred1 are estimated from parameters of + the remaining bands with ptrans0 <= b < btrans1. */ + // bpred1 = ( hStereoDft->nbands > 10 ) ? STEREO_DFT_RES_PRED_BAND_MAX - 2 : hStereoDft->nbands; + IF( GT_16( hStereoDft->nbands, 10 ) ) { - push_indice( hBstr, IND_STEREO_DFT_GIPD, hStereoDft->gipd_index, STEREO_DFT_GIPD_NBITS ); - nb += STEREO_DFT_GIPD_NBITS; + bpred1 = STEREO_DFT_RES_PRED_BAND_MAX - 2; + move16(); } - } - else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS ) ) - { - push_indice( hBstr, IND_STEREO_DFT_NO_IPD_FLAG, hStereoDft->no_ipd_flag, STEREO_DFT_FLAG_BITS ); - nb += STEREO_DFT_FLAG_BITS; /*IPD mode flag: 1bit*/ - - if ( hStereoDft->no_ipd_flag == 0 ) + ELSE { - stereo_dft_quantize_ipd( &hStereoDft->sid_gipd, &hStereoDft->sid_gipd, &sid_gIpd_index, STEREO_DFT_SID_GIPD_NBITS ); - push_indice( hBstr, IND_STEREO_DFT_GIPD, sid_gIpd_index, STEREO_DFT_SID_GIPD_NBITS ); - nb += STEREO_DFT_SID_GIPD_NBITS; + bpred1 = hStereoDft->nbands; + move16(); } - } - - -#ifdef DEBUG_MODE_DFT_BITS - fprintf( IPD_bits, "%d ", nb ); -#endif - ( *nb_bits ) += nb; - /*----------------------------------------------------------------* - * Residual prediction - *----------------------------------------------------------------*/ + IF( EQ_16( hStereoDft->band_res[k_offset], STEREO_DFT_BAND_RES_LOW ) ) + { + bpred1 = s_min( bpred1, 6 ); + } + bpred0 = sub( bpred1, STEREO_DFT_RES_PRED_BAND_MIN_CONST ); - nb = 0; /* bits for residual pred gains */ - if ( hStereoDft->res_pred_mode[k_offset] ) - { - if ( hStereoDft->attackPresent == 0 ) + /* get estimate (currently the maximal index) */ + FOR( b = hStereoDft->res_pred_band_min; b < bpred0; b++ ) { - nbands = min( hStereoDft->nbands, STEREO_DFT_RES_PRED_BAND_MAX ); - b = hStereoDft->res_pred_band_min; + ipred = s_max( ipred, hStereoDft->res_pred_index_EC[b] ); + } - /*Adaptive SF*/ - if ( hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) - { - /*read flag*/ - push_indice( hBstr, IND_STEREO_DFT_REVERB_MODE, hStereoDft->reverb_flag, STEREO_DFT_REVERB_MODE_NBITS ); - nb += STEREO_DFT_REVERB_MODE_NBITS; - if ( hStereoDft->reverb_flag ) - { - nbands -= STEREO_DFT_RES_PRED_BAND_MIN_CONST; - } - } + /* check prediction error */ + FOR( b = bpred0; b < bpred1; b++ ) + { + max_dev = s_max( max_dev, abs_s( sub( ipred, hStereoDft->res_pred_index_EC[b] ) ) ); + sum_abs_dev = add( sum_abs_dev, abs_s( sub( ipred, hStereoDft->res_pred_index_EC[b] ) ) ); + } - /* Res Pred Gain flag 0 */ - if ( hStereoDft->res_pred_flag_1 > 0 ) - { - push_indice( hBstr, IND_STEREO_DFT_RES_PRED_FLAG, hStereoDft->res_pred_flag_1, 2 ); - nb += 2; /*pred gain mode flag: 2 bits*/ - } - else - { - push_indice( hBstr, IND_STEREO_DFT_RES_PRED_FLAG, hStereoDft->res_pred_flag_1, STEREO_DFT_FLAG_BITS ); - nb += STEREO_DFT_FLAG_BITS; /*pred gain mode flag: 1bit*/ - } + test(); + hStereoDft->reverb_flag = ( LE_16( max_dev, 1 ) && LE_16( sum_abs_dev, 2 ) ); - no_GR_ord = 2; - if ( hStereoDft->res_pred_flag_1 == 0 ) - { - if ( encoded_ind_pred_GR[0] == dft_maps_rpg[8 * NO_SYMB_GR_PRED_G] ) - { - nb += write_GR1( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, 1 ); - } - else - { - nb += write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2, 2 ); - } - } - else + test(); + IF( hStereoDft->reverb_flag && GT_16( hStereoDft->nbands, 10 ) ) /*SWB and FB*/ + { + FOR( b = STEREO_DFT_RES_PRED_BAND_MAX - 1; b >= STEREO_DFT_RES_PRED_BAND_MAX - 2; b-- ) { - if ( hStereoDft->res_pred_flag_1 == 2 ) - { - nb += write_bitstream_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2 - no_GR_ord ); - } - else - { - for ( b = hStereoDft->res_pred_band_min; b < nbands; b++ ) - { - push_indice( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, hStereoDft->res_pred_index_EC[b], STEREO_DFT_RES_GAINS_BITS ); - nb += STEREO_DFT_RES_GAINS_BITS; - } - } + hStereoDft->res_pred_index_EC[b - STEREO_DFT_RES_PRED_BAND_MIN_CONST] = hStereoDft->res_pred_index_EC[b]; + move16(); } } - else - { - set_s( hStereoDft->res_pred_index_ECprevious, 0, hStereoDft->nbands - hStereoDft->res_pred_band_min ); - } - } - else - { - set_s( hStereoDft->res_pred_index_ECprevious, 0, hStereoDft->nbands - hStereoDft->res_pred_band_min ); - } - - ( *nb_bits ) += nb; - - if ( core_brate == SID_2k40 ) - { - stereo_dft_enc_sid_coh( hBstr, hCPE->hStereoCng->mem_cohBand, hStereoDft->nbands, nb_bits, cohBand ); } - - return; -} - - -/*------------------------------------------------------------------------- - * stereo_dft_enc_compute_prm() - * - * Compute stereo parameters: IPD and SIDE_GAIN - * SIDE_GAIN: Interchannel Level Difference - * IPD: Interchannel Phase Difference: angle(L)-angle(R) = acos(/(|L|.|R|)) or atan2(Img(L.R*)/Re(L.R*)) - *------------------------------------------------------------------------*/ - + assert( hStereoDft->nbands <= 13 ); /* always use band_limits_erb4 and not band_limits_erb2 */ + + return; +} +#else static void stereo_dft_enc_compute_prm( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, float *DFT_L, @@ -4653,7 +5437,7 @@ static void stereo_dft_enc_compute_prm( return; } - +#endif /*---------------------------------------------------------------------* * side_gain_mode_decision() @@ -4824,7 +5608,68 @@ static void res_pred_gain_mode_decision( * * Calculate mean of previous bandwise IPD values *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 ipd_table1[STEREO_DFT_IPD_BUF_LEN] = { 0, 16384, 21845, 24576, 26214 }; //(i / (float)(i + 1)) +static Word16 ipd_table2[STEREO_DFT_IPD_BUF_LEN] = { MAX_16, 16384, 10923, 8192, 6554 }; //(1 / (float)(i + 1)) +static Word32 stereo_dft_calc_mean_bipd_fx( + Word32 *pIpd, /* i : current bandwise IPD Q13 */ + Word32 ipd_buf[STEREO_DFT_IPD_BUF_LEN] /* i/o: previous bandwise IPDs Q13 */ +) +{ + Word16 i; + Word32 ipd_smooth; + Word32 diff_to_last; + + assert( *pIpd <= EVS_PI_FX && *pIpd >= -EVS_PI_FX ); + + ipd_smooth = 0; + move16(); + FOR( i = 0; i < STEREO_DFT_IPD_BUF_LEN; i++ ) + { + IF( i == 0 ) + { + diff_to_last = ipd_buf[0]; + move32(); + } + ELSE + { + diff_to_last = L_abs( L_sub( ipd_buf[i], ipd_smooth ) ); + } + IF( GT_32( diff_to_last, EVS_PI_FX ) ) + { + IF( ipd_buf[i] > 0 ) + { + ipd_buf[i] = L_sub( ipd_buf[i], 2 * EVS_PI_FX ); + } + ELSE + { + ipd_buf[i] = L_add( ipd_buf[i], 2 * EVS_PI_FX ); + } + } + // ipd_smooth = (i / (float)(i + 1)) * ipd_smooth + (1 / (float)(i + 1)) * ipd_buf[i]; + ipd_smooth = L_add( Mpy_32_16_1( ipd_smooth, ipd_table1[i] ), Mpy_32_16_1( ipd_buf[i], ipd_table2[i] ) ); // Q13 + IF( LT_32( ipd_smooth, -EVS_PI_FX ) ) + { + ipd_smooth = L_add( ipd_smooth, 2 * EVS_PI_FX ); + } + ELSE IF( GT_32( ipd_smooth, EVS_PI_FX ) ) + { + ipd_smooth = L_sub( ipd_smooth, 2 * EVS_PI_FX ); + } + } + + FOR( i = 0; i < STEREO_DFT_IPD_BUF_LEN - 1; i++ ) + { + ipd_buf[i] = ipd_buf[i + 1]; + move32(); + } + ipd_buf[STEREO_DFT_IPD_BUF_LEN - 1] = *pIpd; + move32(); + + return ipd_smooth; +} +#else static float stereo_dft_calc_mean_bipd( float *pIpd, /* i : current bandwise IPD */ float ipd_buf[STEREO_DFT_IPD_BUF_LEN] /* i/o: previous bandwise IPDs */ @@ -4878,14 +5723,46 @@ static float stereo_dft_calc_mean_bipd( return ipd_smooth; } - +#endif /*------------------------------------------------------------------------- * stereo_dft_calc_mean_ipd_change() * * Calculate mean IPD change over all bands *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word32 stereo_dft_calc_mean_ipd_change_fx( + Word32 *pIpd, /* i : bandwise IPDs Q13 */ + Word32 *ipd_smooth, /* i : mean of previous bandwise IPDs Q13 */ + Word16 gipd_band_max /* i : number of IPD bands */ +) +{ + Word16 b; + Word32 ipd_mean_change; // Q13 + Word16 ipd_mean_change_e; + Word32 ipd_change[STEREO_DFT_BAND_MAX]; // Q13 + + ipd_mean_change = 0; + move32(); + FOR( b = 0; b < gipd_band_max; b++ ) + { + ipd_change[b] = L_abs( L_sub( pIpd[b], ipd_smooth[b] ) ); + move32(); + IF( GT_32( ipd_change[b], EVS_PI_FX ) ) + { + ipd_change[b] = L_sub( 2 * EVS_PI_FX, ipd_change[b] ); + move32(); + } + ipd_mean_change = L_add( ipd_mean_change, ipd_change[b] ); + } + // ipd_mean_change /= gipd_band_max; + ipd_mean_change = BASOP_Util_Divide3232_Scale_cadence( ipd_mean_change, gipd_band_max, &ipd_mean_change_e ); + ipd_mean_change_e = add( ipd_mean_change_e, 18 - 31 ); + ipd_mean_change = L_shr( ipd_mean_change, sub( 18, ipd_mean_change_e ) ); + return ipd_mean_change; +} +#else static float stereo_dft_calc_mean_ipd_change( float *pIpd, /* i : bandwise IPDs */ float *ipd_smooth, /* i : mean of previous bandwise IPDs */ @@ -4911,13 +5788,77 @@ static float stereo_dft_calc_mean_ipd_change( return ipd_mean_change; } - +#endif /*------------------------------------------------------------------------- * stereo_dft_gipd_stabilization() * * stabilize global IPD based on stability of bandwise IPDs *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_gipd_stabilization_fx( + Word32 *pgIpd, /* i/o: global IPD to be stabilized Q13 */ + Word32 prev_gipd, /* i : previous global IPD Q13 */ + Word32 ipd_mean_change /* i : mean of previous bandwise IPDs Q13 */ +) +{ + Word32 diff_gipd; + + IF( LT_32( ipd_mean_change, 2458 /*0.3f in Q13*/ ) ) + { + *pgIpd = prev_gipd; + move32(); + } + ELSE + { + diff_gipd = L_abs( L_sub( *pgIpd, prev_gipd ) ); + if ( GT_32( diff_gipd, EVS_PI_FX ) ) + { + diff_gipd = L_sub( 2 * EVS_PI_FX, diff_gipd ); + } + IF( GT_32( diff_gipd, ipd_mean_change ) ) + { + IF( GT_32( *pgIpd, prev_gipd ) ) + { + IF( LT_32( L_sub( *pgIpd, prev_gipd ), EVS_PI_FX ) ) + { + *pgIpd = L_add( prev_gipd, ipd_mean_change ); + move32(); + } + ELSE + { + *pgIpd = L_sub( prev_gipd, ipd_mean_change ); + move32(); + if ( LT_32( *pgIpd, -EVS_PI_FX ) ) + { + *pgIpd = L_add( *pgIpd, 2 * EVS_PI_FX ); + move32(); + } + } + } + ELSE + { + IF( LT_32( L_sub( prev_gipd, *pgIpd ), EVS_PI_FX ) ) + { + *pgIpd = L_sub( prev_gipd, ipd_mean_change ); + move32(); + } + ELSE + { + *pgIpd = L_add( prev_gipd, ipd_mean_change ); + move32(); + if ( GT_32( *pgIpd, EVS_PI_FX ) ) + { + *pgIpd = L_sub( *pgIpd, 2 * EVS_PI_FX ); + move32(); + } + } + } + } + } + return; +} +#else static void stereo_dft_gipd_stabilization( float *pgIpd, /* i/o: global IPD to be stabilized */ @@ -4974,14 +5915,57 @@ static void stereo_dft_gipd_stabilization( } return; } - +#endif /*------------------------------------------------------------------------- * stereo_dft_enc_get_nipd_flag() * * *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_enc_get_nipd_flag_fx( + STEREO_DFT_ENC_DATA_HANDLE hStereoDft, + const Word16 sp_aud_decision0, + const Word32 gainIPD ) +{ + // hStereoDft->gainIPD_sm = 0.5f * hStereoDft->gainIPD_sm + 0.5f * gainIPD; /* to decide on use of no IPD */ + hStereoDft->gainIPD_sm_fx = L_add( L_shr( hStereoDft->gainIPD_sm_fx, 1 ), L_shr( gainIPD, 1 ) ); /* to decide on use of no IPD */ + move32(); + + hStereoDft->no_ipd_flag = 0; /* Set flag initially to zero - subband IPD */ + move16(); + + // if (hStereoDft->gainIPD_sm >= 0.75f || (hStereoDft->prev_no_ipd_flag && (sp_aud_decision0 || hStereoDft->voicing_lt > 0.98f))) + test(); + test(); + test(); + if ( GE_32( hStereoDft->gainIPD_sm_fx, 1610612736 /*0.75f in Q31*/ ) || ( hStereoDft->prev_no_ipd_flag && ( sp_aud_decision0 || GT_32( hStereoDft->voicing_lt_fx, 2104533975 /*0.98f in Q31*/ ) ) ) ) + { + hStereoDft->no_ipd_flag = 1; /* Set the flag */ + move16(); + } + + + /* hangover between the group IPD and subband IPD */ + test(); + IF( NE_16( hStereoDft->prev_no_ipd_flag, hStereoDft->no_ipd_flag ) && LT_16( hStereoDft->no_ipd_cnt, 5 ) ) + { + hStereoDft->no_ipd_flag = hStereoDft->prev_no_ipd_flag; + move16(); + hStereoDft->no_ipd_cnt = add( hStereoDft->no_ipd_cnt, 1 ); + } + ELSE + { + hStereoDft->no_ipd_cnt = 0; + move16(); + } + + hStereoDft->prev_no_ipd_flag = hStereoDft->no_ipd_flag; /* Save the no IPD flag for the next frame */ + move16(); + return; +} +#else static void stereo_dft_enc_get_nipd_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, const int16_t sp_aud_decision0, @@ -5013,14 +5997,331 @@ static void stereo_dft_enc_get_nipd_flag( return; } - +#endif /*--------------------------------------------------------------- * stereo_dft_enc_get_reverb_flag() * * * ---------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void stereo_dft_enc_get_reverb_flag_fx( + STEREO_DFT_ENC_DATA_HANDLE hStereoDft, + Word32 *pPredGain, // Q31 + Word32 *sub_nrg_DMX, + Word16 *sub_nrg_DMX_e, + const Word32 *sub_nrg_L, // Q(31-sub_nrg_L_e[]) + const Word16 *sub_nrg_L_e, + const Word32 *sub_nrg_R, // Q(31-sub_nrg_R_e[]) + const Word16 *sub_nrg_R_e, + const Word16 k_offset, + const Word32 *bin_nrgL, // Q(31-bin_nrgL_e[]) + const Word16 *bin_nrgL_e, + const Word32 *bin_nrgR, // Q(31-bin_nrgR_e[]) + const Word16 *bin_nrgR_e ) +{ + Word16 i, b, b1, index_min, nbands; + Word32 nrg_DMX_min; + Word16 nrg_DMX_min_e; + Word32 norm_r, norm_l, norm_dmx; + Word16 norm_r_e, norm_l_e, norm_dmx_e; + Word32 diff_l_l, diff_r_l, diff_l_h, diff_r_h; + Word16 diff_l_l_e, diff_r_l_e, diff_l_h_e, diff_r_h_e; + Word32 ener_l, ener_r, ener_dmx; + Word16 ener_l_e, ener_r_e, ener_dmx_e; + Word32 nrg_DMX_max_avrg, nrg_DMX_min_avrg; + Word16 nrg_DMX_max_avrg_e, nrg_DMX_min_avrg_e; + Word32 fac; + Word32 L_tmp; + Word16 L_tmp_e; + + hStereoDft->reverb_flag = 0; + move16(); + test(); + IF( hStereoDft->res_pred_mode[k_offset] && EQ_16( hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) + { + diff_r_l = EPSILON_FX_M; + move32(); + diff_r_l_e = EPSILON_FX_E; + move16(); + diff_l_l = EPSILON_FX_M; + move32(); + diff_l_l_e = EPSILON_FX_E; + move16(); + diff_r_h = EPSILON_FX_M; + move32(); + diff_r_h_e = EPSILON_FX_E; + move16(); + diff_l_h = EPSILON_FX_M; + move32(); + diff_l_h_e = EPSILON_FX_E; + move16(); + + FOR( b = 0; b <= s_min( hStereoDft->nbands, 6 ); b++ ) /* choose the subbands used for stereo filling */ + { + // norm_dmx = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_DMX[b]); + norm_dmx = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_DMX[b], &norm_dmx_e ); + norm_dmx_e = add( norm_dmx_e, sub( 31, sub_nrg_DMX_e[b] ) ); + // norm_l = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_L[b]); + norm_l = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_L[b], &norm_l_e ); + norm_l_e = add( norm_l_e, sub( 31, sub_nrg_L_e[b] ) ); + // norm_r = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_R[b]); + norm_r = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_R[b], &norm_r_e ); + norm_r_e = add( norm_r_e, sub( 31, sub_nrg_R_e[b] ) ); + + FOR( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) /* normalization on each subbands */ + { + ener_l = bin_nrgL[i]; + move32(); + ener_l_e = bin_nrgL_e[i]; + move16(); + ener_r = bin_nrgR[i]; + move32(); + ener_r_e = bin_nrgR_e[i]; + move16(); + // ener_dmx = (ener_l + ener_r + 2 * sqrtf(ener_l * ener_r)) * norm_dmx; /*approximation of nrg of DMX per line*/ + L_tmp = Mpy_32_32( ener_l, ener_r ); + L_tmp_e = add( ener_l_e, ener_r_e ); + L_tmp = Sqrt32( L_tmp, &L_tmp_e ); + L_tmp = Mpy_32_32( L_tmp, norm_dmx ); + L_tmp_e = add( add( L_tmp_e, norm_dmx_e ), 1 ); + L_tmp = BASOP_Util_Add_Mant32Exp( ener_l, ener_l_e, L_tmp, L_tmp_e, &L_tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( ener_r, ener_r_e, L_tmp, L_tmp_e, &L_tmp_e ); + ener_dmx = L_tmp; + move32(); + ener_dmx_e = L_tmp_e; + move16(); + + // ener_l *= norm_l; + ener_l = Mpy_32_32( ener_l, norm_l ); + ener_l_e = add( ener_l_e, norm_l_e ); + // ener_r *= norm_r; + ener_r = Mpy_32_32( ener_r, norm_r ); + ener_r_e = add( ener_r_e, norm_r_e ); + + // diff_l_l += fabsf(ener_l - ener_dmx); + L_tmp = L_abs( BASOP_Util_Add_Mant32Exp( ener_l, ener_l_e, L_negate( ener_dmx ), ener_dmx_e, &L_tmp_e ) ); + diff_l_l = BASOP_Util_Add_Mant32Exp( diff_l_l, diff_l_l_e, L_tmp, L_tmp_e, &diff_l_l_e ); + // diff_r_l += fabsf(ener_r - ener_dmx); + L_tmp = L_abs( BASOP_Util_Add_Mant32Exp( ener_r, ener_r_e, L_negate( ener_dmx ), ener_dmx_e, &L_tmp_e ) ); + diff_r_l = BASOP_Util_Add_Mant32Exp( diff_r_l, diff_r_l_e, L_tmp, L_tmp_e, &diff_r_l_e ); + } + } + IF( LE_16( hStereoDft->nbands, 10 ) ) + { + FOR( ; b < s_min( hStereoDft->nbands, 10 ); b++ ) /* choose the subbands used for stereo filling */ + { + // norm_dmx = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_DMX[b]); + norm_dmx = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_DMX[b], &norm_dmx_e ); + norm_dmx_e = add( norm_dmx_e, sub( 31, sub_nrg_DMX_e[b] ) ); + // norm_l = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_L[b]); + norm_l = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_L[b], &norm_l_e ); + norm_l_e = add( norm_l_e, sub( 31, sub_nrg_L_e[b] ) ); + // norm_r = ((hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]) / sub_nrg_R[b]); + norm_r = BASOP_Util_Divide3232_Scale_cadence( sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), sub_nrg_R[b], &norm_r_e ); + norm_r_e = add( norm_r_e, sub( 31, sub_nrg_R_e[b] ) ); + + FOR( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) /* normalization on each subbands */ + { + ener_l = bin_nrgL[i]; + move32(); + ener_l_e = bin_nrgL_e[i]; + move16(); + ener_r = bin_nrgR[i]; + move32(); + ener_r_e = bin_nrgR_e[i]; + move16(); + // ener_dmx = (ener_l + ener_r + 2 * sqrtf(ener_l * ener_r)) * norm_dmx; /*approximation of nrg of DMX per line*/ + L_tmp = Mpy_32_32( ener_l, ener_r ); + L_tmp_e = add( ener_l_e, ener_r_e ); + L_tmp = Sqrt32( L_tmp, &L_tmp_e ); + L_tmp = Mpy_32_32( L_tmp, norm_dmx ); + L_tmp_e = add( add( L_tmp_e, norm_dmx_e ), 1 ); + L_tmp = BASOP_Util_Add_Mant32Exp( ener_l, ener_l_e, L_tmp, L_tmp_e, &L_tmp_e ); + L_tmp = BASOP_Util_Add_Mant32Exp( ener_r, ener_r_e, L_tmp, L_tmp_e, &L_tmp_e ); + ener_dmx = L_tmp; + move32(); + ener_dmx_e = L_tmp_e; + move16(); + + // ener_l *= norm_l; + ener_l = Mpy_32_32( ener_l, norm_l ); + ener_l_e = add( ener_l_e, norm_l_e ); + // ener_r *= norm_r; + ener_r = Mpy_32_32( ener_r, norm_r ); + ener_r_e = add( ener_r_e, norm_r_e ); + + // diff_l_h += fabsf(ener_l - ener_dmx); + L_tmp = L_abs( BASOP_Util_Add_Mant32Exp( ener_l, ener_l_e, L_negate( ener_dmx ), ener_dmx_e, &L_tmp_e ) ); + diff_l_h = BASOP_Util_Add_Mant32Exp( diff_l_h, diff_l_h_e, L_tmp, L_tmp_e, &diff_l_h_e ); + // diff_r_h += fabsf(ener_r - ener_dmx); + L_tmp = L_abs( BASOP_Util_Add_Mant32Exp( ener_r, ener_r_e, L_negate( ener_dmx ), ener_dmx_e, &L_tmp_e ) ); + diff_r_h = BASOP_Util_Add_Mant32Exp( diff_r_h, diff_r_h_e, L_tmp, L_tmp_e, &diff_r_h_e ); + } + } + } + + FOR( b = 0; b < hStereoDft->nbands; b++ ) /* choose the subbands used for stereo filling */ + { + // sub_nrg_DMX[b] /= (hStereoDft->band_limits[b + 1] - hStereoDft->band_limits[b]); + sub_nrg_DMX[b] = BASOP_Util_Divide3232_Scale_cadence( sub_nrg_DMX[b], sub( hStereoDft->band_limits[b + 1], hStereoDft->band_limits[b] ), &L_tmp_e ); + move32(); + sub_nrg_DMX_e[b] = add( L_tmp_e, sub( sub_nrg_DMX_e[b], 31 ) ); + move16(); + // sub_nrg_DMX[b] = 0.6f * hStereoDft->pre_sub_nrg_DMX[b] + 0.4f * sub_nrg_DMX[b]; + sub_nrg_DMX[b] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 1288490189 /*0.6f*/, hStereoDft->pre_sub_nrg_DMX_fx[b] ), hStereoDft->pre_sub_nrg_DMX_fx_e[b], Mpy_32_32( 858993459 /*0.4f*/, sub_nrg_DMX[b] ), sub_nrg_DMX_e[b], &sub_nrg_DMX_e[b] ); + move32(); + hStereoDft->pre_sub_nrg_DMX_fx[b] = sub_nrg_DMX[b]; + move32(); + hStereoDft->pre_sub_nrg_DMX_fx_e[b] = sub_nrg_DMX_e[b]; + move16(); + } + + /* adaptively select the subbands to predict based on the energy */ + // nbands = (hStereoDft->nbands > 10) ? (hStereoDft->nbands - 2) : hStereoDft->nbands; + IF( GT_16( hStereoDft->nbands, 10 ) ) + { + nbands = sub( hStereoDft->nbands, 2 ); + } + ELSE + { + nbands = hStereoDft->nbands; + move16(); + } + + nrg_DMX_min_avrg = 0; + move32(); + nrg_DMX_min_avrg_e = 0; + move16(); + FOR( b = 2; b < STEREO_DFT_RES_PRED_BAND_MIN_RED; b++ ) + { + nrg_DMX_min = sub_nrg_DMX[b]; + move32(); + nrg_DMX_min_e = sub_nrg_DMX_e[b]; + move16(); + index_min = b; + move16(); + + FOR( b1 = 2; b1 < nbands; b1++ ) + { + // if (nrg_DMX_min > sub_nrg_DMX[b1]) + IF( BASOP_Util_Cmp_Mant32Exp( nrg_DMX_min, nrg_DMX_min_e, sub_nrg_DMX[b1], sub_nrg_DMX_e[b1] ) > 0 ) + { + nrg_DMX_min = sub_nrg_DMX[b1]; + move32(); + nrg_DMX_min_e = sub_nrg_DMX_e[b1]; + move16(); + index_min = b1; + move16(); + } + } + + // nrg_DMX_min_avrg += nrg_DMX_min; + nrg_DMX_min_avrg = BASOP_Util_Add_Mant32Exp( nrg_DMX_min_avrg, nrg_DMX_min_avrg_e, nrg_DMX_min, nrg_DMX_min_e, &nrg_DMX_min_avrg_e ); + // sub_nrg_DMX[index_min] = FLT_MAX; + sub_nrg_DMX[index_min] = MAX_32; + move32(); + sub_nrg_DMX_e[index_min] = 128; + move16(); + } + + nrg_DMX_max_avrg = 0; + move32(); + nrg_DMX_max_avrg_e = 0; + move16(); + FOR( ( b = 2, b1 = STEREO_DFT_RES_PRED_BAND_MIN_RED ); b < nbands; b++ ) + { + // if (sub_nrg_DMX[b] != FLT_MAX) + IF( BASOP_Util_Cmp_Mant32Exp( sub_nrg_DMX[b], sub_nrg_DMX_e[b], MAX_32, 128 ) != 0 ) + { + // nrg_DMX_max_avrg += sub_nrg_DMX[b]; + nrg_DMX_max_avrg = BASOP_Util_Add_Mant32Exp( nrg_DMX_max_avrg, nrg_DMX_max_avrg_e, sub_nrg_DMX[b], sub_nrg_DMX_e[b], &nrg_DMX_max_avrg_e ); + } + } + + IF( LE_16( hStereoDft->nbands, 10 ) ) /*WB*/ + { + test(); + IF( EQ_16( hStereoDft->res_pred_mode[0], STEREO_DFT_RESPRED_OFF ) || NE_16( hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) + { + hStereoDft->diff_l_h_sm_fx = diff_l_h; + move32(); + hStereoDft->diff_l_h_sm_fx_e = diff_l_h_e; + move16(); + hStereoDft->diff_r_h_sm_fx = diff_r_h; + move32(); + hStereoDft->diff_r_h_sm_fx_e = diff_r_h_e; + move16(); + } + ELSE + { + // hStereoDft->diff_l_h_sm = 0.9f * hStereoDft->diff_l_h_sm + 0.1f * diff_l_h; + hStereoDft->diff_l_h_sm_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 1932735283 /*0.9f*/, hStereoDft->diff_l_h_sm_fx ), hStereoDft->diff_l_h_sm_fx_e, Mpy_32_32( 214748365 /*0.1f*/, diff_l_h ), diff_l_h_e, &hStereoDft->diff_l_h_sm_fx_e ); + move32(); + // hStereoDft->diff_r_h_sm = 0.9f * hStereoDft->diff_r_h_sm + 0.1f * diff_r_h; + hStereoDft->diff_r_h_sm_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( 1932735283 /*0.9f*/, hStereoDft->diff_r_h_sm_fx ), hStereoDft->diff_r_h_sm_fx_e, Mpy_32_32( 214748365 /*0.1f*/, diff_r_h ), diff_r_h_e, &hStereoDft->diff_r_h_sm_fx_e ); + move32(); + } + + // if (hStereoDft->diff_l_h_sm > 120.0f || hStereoDft->diff_r_h_sm > 120.0f) + test(); + if ( BASOP_Util_Cmp_Mant32Exp( hStereoDft->diff_l_h_sm_fx, hStereoDft->diff_l_h_sm_fx_e, 120, 31 ) > 0 || BASOP_Util_Cmp_Mant32Exp( hStereoDft->diff_r_h_sm_fx, hStereoDft->diff_r_h_sm_fx_e, 120, 31 ) > 0 ) + { + hStereoDft->reverb_flag = 1; + move16(); + } + } + ELSE /*SWB/FB*/ + { + // if (3 * nrg_DMX_max_avrg > 64 * 5 * nrg_DMX_min_avrg) + if ( BASOP_Util_Cmp_Mant32Exp( Mpy_32_32( 1288490189 /*3/5 in Q31*/, nrg_DMX_max_avrg ), nrg_DMX_max_avrg_e, nrg_DMX_min_avrg, add( nrg_DMX_min_avrg_e, 6 /* * 64 */ ) ) > 0 ) + { + hStereoDft->reverb_flag = 1; + move16(); + } + } + + /*Stereo Filling gain damping*/ + // fac = ((diff_l_l > diff_r_l) ? diff_r_l / diff_l_l : diff_l_l / diff_r_l); + IF( BASOP_Util_Cmp_Mant32Exp( diff_l_l, diff_l_l_e, diff_r_l, diff_r_l_e ) > 0 ) + { + fac = BASOP_Util_Divide3232_Scale_cadence( diff_r_l, diff_l_l, &L_tmp_e ); + L_tmp_e = add( L_tmp_e, sub( diff_r_l_e, diff_l_l_e ) ); + } + ELSE + { + fac = BASOP_Util_Divide3232_Scale_cadence( diff_l_l, diff_r_l, &L_tmp_e ); + L_tmp_e = add( L_tmp_e, sub( diff_l_l_e, diff_r_l_e ) ); + } + fac = L_shl_sat( fac, L_tmp_e ); // Q31 + // fac = fac > 0.25f ? 1.0f : 4.f * fac; + fac = L_shl_sat( fac, 2 ); + // fac = 0.98f * hStereoDft->prev_fac2 + 0.02f * fac; + fac = L_add( Mpy_32_32( 2104533975 /*0.98f*/, hStereoDft->prev_fac2_fx ), Mpy_32_32( 42949673 /*0.02f*/, fac ) ); + hStereoDft->prev_fac2_fx = fac; + move32(); + + FOR( b = 0; b < hStereoDft->nbands; b++ ) + { + IF( LT_16( b, 5 ) ) + { + // pPredGain[b] *= max(0.5f, fac); + pPredGain[b] = Mpy_32_32( pPredGain[b], L_max( ONE_IN_Q30, fac ) ); + move32(); + } + ELSE + { + // pPredGain[b] *= min(1.0f, max(0.75f, 0.5f + fac)); + pPredGain[b] = Mpy_32_32( pPredGain[b], L_max( 1610612736 /*0.75f*/, L_add_sat( ONE_IN_Q30, fac ) ) ); + move32(); + } + } + } + + return; +} +#else static void stereo_dft_enc_get_reverb_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, float *pPredGain, @@ -5172,13 +6473,53 @@ static void stereo_dft_enc_get_reverb_flag( return; } - +#endif /*--------------------------------------------------------------- * stereo_dft_gain_offset() * * c = gain between L and R, itd = itd in samples @ 32kHz * ---------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word32 stereo_dft_gain_offset_fx( + const Word32 c, // Q(31-c_e) + const Word16 c_e, + const Word16 itd ) +{ + Word32 wnt, go, alpha; + Word16 alpha_e; + Word16 tau, k0; + Word32 L_tmp, L_tmp1, L_tmp2; + Word16 L_tmp_e, L_tmp1_e, L_tmp2_e; + + tau = s_min( abs_s( itd ), 160 ); // Q0 + /* Wn_table contains every 8th sample of the window's cross-correlation + * function @ 32kHz from which the values are interpolated: */ + k0 = shr( tau, 3 ); + // alpha = s_and(tau, 7) / 8.f; + alpha = BASOP_Util_Divide3232_Scale_cadence( s_and( tau, 7 ), 8, &alpha_e ); + alpha = L_shl( alpha, alpha_e ); // Q31 + // wnt = (1 - alpha) * Wn_table[k0] + alpha * Wn_table[k0 + 1]; + wnt = L_add( Mpy_32_32( L_sub( MAX_32, alpha ), Wn_table_fx[k0] ), Mpy_32_32( alpha, Wn_table_fx[k0 + 1] ) ); // Q31 + + // go = sqrtf(8 * c * c / ((1 + c) * (1 + c)) * (1 - wnt) / (1 + c * c + 2 * c * wnt)); + L_tmp = Mpy_32_32( c, c ); + L_tmp_e = shl( c_e, 1 ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( MAX_32, 0, c, c_e, &L_tmp1_e ); + L_tmp1 = Mpy_32_32( L_tmp1, L_tmp1 ); + L_tmp1_e = shl( L_tmp1_e, 1 ); + L_tmp2 = BASOP_Util_Divide3232_Scale_cadence( L_tmp, L_tmp1, &L_tmp2_e ); + L_tmp2_e = add( add( L_tmp2_e, sub( L_tmp_e, L_tmp1_e ) ), 3 /*multiply by 8*/ ); + L_tmp2 = Mpy_32_32( L_tmp2, L_sub( MAX_32, wnt ) ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( MAX_32, 0, L_tmp, L_tmp_e, &L_tmp1_e ); + L_tmp1 = BASOP_Util_Add_Mant32Exp( L_tmp1, L_tmp1_e, Mpy_32_32( c, wnt ), add( c_e, 1 ), &L_tmp1_e ); + L_tmp = BASOP_Util_Divide3232_Scale_cadence( L_tmp2, L_tmp1, &L_tmp_e ); + L_tmp_e = add( L_tmp_e, sub( L_tmp2_e, L_tmp1_e ) ); + L_tmp = Sqrt32( L_tmp, &L_tmp_e ); + go = L_shl( L_tmp, L_tmp_e ); + return go; +} +#else static float stereo_dft_gain_offset( const float c, const int16_t itd ) @@ -5197,6 +6538,7 @@ static float stereo_dft_gain_offset( return go; } +#endif /*--------------------------------------------------------------- * stereo_dft_enc_calculate_nrg_for_icbwe() diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c index e97e32f9176bc46a5549ffb9e67201c3dbd11e5f..b7f2af7f9a9f0f38a8cf8ad2f672d2dbc4f890b8 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -1330,9 +1330,9 @@ static float peak_detect( void stereo_dft_enc_compute_itd_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ Word32 *DFT_L, - Word16 DFT_L_e, + Word16 *DFT_L_e, Word32 *DFT_R, - Word16 DFT_R_e, + Word16 *DFT_R_e, const Word16 k_offset, const Word16 input_frame, const Word16 vad_flag_dtx[], @@ -1346,7 +1346,8 @@ void stereo_dft_enc_compute_itd_fx( STEREO_DFT_ENC_DATA_HANDLE hStereoDft; ITD_DATA_HANDLE hItd; Word32 *pDFT_L, *pDFT_R; - Word16 DFT_L_e_tmp[STEREO_DFT_N_MAX_ENC], DFT_R_e_tmp[STEREO_DFT_N_MAX_ENC]; + // Word32 DFT_L_tmp[STEREO_DFT_N_MAX_ENC], DFT_R_tmp[STEREO_DFT_N_MAX_ENC]; + // Word16 DFT_L_e_tmp[STEREO_DFT_N_MAX_ENC], DFT_R_e_tmp[STEREO_DFT_N_MAX_ENC]; Word32 abs_L, abs_R, prod_L, prod_R, sum_abs_L, sum_abs_R; Word16 abs_L_e, abs_R_e, prod_L_e, prod_R_e, sum_abs_L_e, sum_abs_R_e; Word32 log_prod_L, log_prod_R; @@ -1417,6 +1418,8 @@ void stereo_dft_enc_compute_itd_fx( Word16 q_temp; Word64 W_temp; Word16 W_temp_q; + Word32 tmp; + Word16 exp; IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) { hStereoDft = hCPE->hStereoDft; @@ -1473,23 +1476,6 @@ void stereo_dft_enc_compute_itd_fx( pDFT_L = DFT_L; pDFT_R = DFT_R; -#ifdef MSAN_FIX - FOR( i = 0; i < NFFT; i++ ) -#else - FOR( i = 0; i < STEREO_DFT_N_MAX_ENC; i++ ) -#endif // MSAN_FIX - { - L_temp_e = norm_l( pDFT_L[i] ); - pDFT_L[i] = L_shl( pDFT_L[i], L_temp_e ); - move32(); - DFT_L_e_tmp[i] = sub( DFT_L_e, L_temp_e ); - move16(); - L_temp_e = norm_l( pDFT_R[i] ); - pDFT_R[i] = L_shl( pDFT_R[i], L_temp_e ); - move32(); - DFT_R_e_tmp[i] = sub( DFT_R_e, L_temp_e ); - move16(); - } pNrgL = bin_nrgL; pNrgL_e = bin_nrgL_e; @@ -1512,7 +1498,7 @@ void stereo_dft_enc_compute_itd_fx( ELSE { // log_prod_L = Mpy_32_32( L_add( BASOP_Util_Log2( L_abs( pDFT_L[0] ) ), L_shl( DFT_L_e_tmp[0], 25 ) ), LOG_E_2 ); - log_prod_L = BASOP_Util_Loge( L_abs( pDFT_L[0] ), DFT_L_e_tmp[0] ); + log_prod_L = BASOP_Util_Loge( L_abs( pDFT_L[0] ), DFT_L_e[0] ); } log_prod_L_e = 6; move16(); @@ -1526,7 +1512,7 @@ void stereo_dft_enc_compute_itd_fx( ELSE { // log_prod_R = Mpy_32_32( L_add( BASOP_Util_Log2( L_abs( pDFT_R[0] ) ), L_shl( DFT_R_e_tmp[0], 25 ) ), LOG_E_2 ); - log_prod_R = BASOP_Util_Loge( L_abs( pDFT_R[0] ), DFT_R_e_tmp[0] ); + log_prod_R = BASOP_Util_Loge( L_abs( pDFT_R[0] ), DFT_R_e[0] ); } log_prod_R_e = 6; move16(); @@ -1540,14 +1526,14 @@ void stereo_dft_enc_compute_itd_fx( prod_R_e = 0; move16(); sum_nrg_L = Mpy_32_32( pDFT_L[0], pDFT_L[0] ) /*+ FLT_MIN*/; - sum_nrg_L_e = shl( DFT_L_e_tmp[0], 1 ); + sum_nrg_L_e = shl( DFT_L_e[0], 1 ); sum_nrg_R = Mpy_32_32( pDFT_R[0], pDFT_R[0] ) /*+ FLT_MIN*/; - sum_nrg_R_e = shl( DFT_R_e_tmp[0], 1 ); - sum_abs_L = BASOP_Util_Add_Mant32Exp( L_abs( pDFT_L[0] ), DFT_L_e_tmp[0], EPSILON_FX_M, EPSILON_FX_E, &sum_abs_L_e ) /*+ EPSILON*/; - sum_abs_R = BASOP_Util_Add_Mant32Exp( L_abs( pDFT_R[0] ), DFT_R_e_tmp[0], EPSILON_FX_M, EPSILON_FX_E, &sum_abs_R_e ) /*+ EPSILON*/; + sum_nrg_R_e = shl( DFT_R_e[0], 1 ); + sum_abs_L = BASOP_Util_Add_Mant32Exp( L_abs( pDFT_L[0] ), DFT_L_e[0], EPSILON_FX_M, EPSILON_FX_E, &sum_abs_L_e ) /*+ EPSILON*/; + sum_abs_R = BASOP_Util_Add_Mant32Exp( L_abs( pDFT_R[0] ), DFT_R_e[0], EPSILON_FX_M, EPSILON_FX_E, &sum_abs_R_e ) /*+ EPSILON*/; xcorr_lb[0] = Mpy_32_32( pDFT_L[0], pDFT_L[0] ); move32(); - xcorr_lb_e[0] = shl( DFT_L_e_tmp[0], 1 ); + xcorr_lb_e[0] = shl( DFT_L_e[0], 1 ); move16(); xcorr_lb[0] = BASOP_Util_Add_Mant32Exp( xcorr_lb[0], xcorr_lb_e[0], EPSILON_FX_M, EPSILON_FX_E, &xcorr_lb_e[0] ) /*+ EPSILON*/; move32(); @@ -1584,17 +1570,17 @@ void stereo_dft_enc_compute_itd_fx( i = i; }*/ // xcorr[2 * i] = pDFT_L[2 * i] * pDFT_R[2 * i] + pDFT_L[2 * i + 1] * pDFT_R[2 * i + 1]; - xcorr[2 * i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i] ), add( DFT_L_e_tmp[2 * i], DFT_R_e_tmp[2 * i] ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i + 1] ), add( DFT_L_e_tmp[2 * i + 1], DFT_R_e_tmp[2 * i + 1] ), &xcorr_e[2 * i] ); + xcorr[2 * i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i] ), add( DFT_L_e[2 * i], DFT_R_e[2 * i] ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i + 1] ), add( DFT_L_e[2 * i + 1], DFT_R_e[2 * i + 1] ), &xcorr_e[2 * i] ); move32(); // xcorr[2 * i + 1] = pDFT_L[2 * i + 1] * pDFT_R[2 * i] - pDFT_L[2 * i] * pDFT_R[2 * i + 1]; - xcorr[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i] ), add( DFT_L_e_tmp[2 * i + 1], DFT_R_e_tmp[2 * i] ), L_negate( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i + 1] ) ), add( DFT_L_e_tmp[2 * i], DFT_R_e_tmp[2 * i + 1] ), &xcorr_e[2 * i + 1] ); + xcorr[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i] ), add( DFT_L_e[2 * i + 1], DFT_R_e[2 * i] ), L_negate( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i + 1] ) ), add( DFT_L_e[2 * i], DFT_R_e[2 * i + 1] ), &xcorr_e[2 * i + 1] ); move32(); // pNrgL[i] = pDFT_L[2 * i] * pDFT_L[2 * i] + pDFT_L[2 * i + 1] * pDFT_L[2 * i + 1]; - pNrgL[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_L[2 * i] ), shl( DFT_L_e_tmp[2 * i], 1 ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_L[2 * i + 1] ), shl( DFT_L_e_tmp[2 * i + 1], 1 ), &pNrgL_e[i] ); + pNrgL[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_L[2 * i] ), shl( DFT_L_e[2 * i], 1 ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_L[2 * i + 1] ), shl( DFT_L_e[2 * i + 1], 1 ), &pNrgL_e[i] ); move32(); // pNrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; - pNrgR[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_R[2 * i], pDFT_R[2 * i] ), shl( DFT_R_e_tmp[2 * i], 1 ), Mpy_32_32( pDFT_R[2 * i + 1], pDFT_R[2 * i + 1] ), shl( DFT_R_e_tmp[2 * i + 1], 1 ), &pNrgR_e[i] ); + pNrgR[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_R[2 * i], pDFT_R[2 * i] ), shl( DFT_R_e[2 * i], 1 ), Mpy_32_32( pDFT_R[2 * i + 1], pDFT_R[2 * i + 1] ), shl( DFT_R_e[2 * i + 1], 1 ), &pNrgR_e[i] ); move32(); Spd_L[i] = pNrgL[i]; @@ -1919,17 +1905,17 @@ void stereo_dft_enc_compute_itd_fx( FOR( ; i < NFFT / 2; i++ ) { // xcorr[2 * i] = pDFT_L[2 * i] * pDFT_R[2 * i] + pDFT_L[2 * i + 1] * pDFT_R[2 * i + 1]; - xcorr[2 * i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i] ), add( DFT_L_e_tmp[2 * i], DFT_R_e_tmp[2 * i] ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i + 1] ), add( DFT_L_e_tmp[2 * i + 1], DFT_R_e_tmp[2 * i + 1] ), &xcorr_e[2 * i] ); + xcorr[2 * i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i] ), add( DFT_L_e[2 * i], DFT_R_e[2 * i] ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i + 1] ), add( DFT_L_e[2 * i + 1], DFT_R_e[2 * i + 1] ), &xcorr_e[2 * i] ); move32(); // xcorr[2 * i + 1] = pDFT_L[2 * i + 1] * pDFT_R[2 * i] - pDFT_L[2 * i] * pDFT_R[2 * i + 1]; - xcorr[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i] ), add( DFT_L_e_tmp[2 * i + 1], DFT_R_e_tmp[2 * i] ), L_negate( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i + 1] ) ), add( DFT_L_e_tmp[2 * i], DFT_R_e_tmp[2 * i + 1] ), &xcorr_e[2 * i + 1] ); + xcorr[2 * i + 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i + 1], pDFT_R[2 * i] ), add( DFT_L_e[2 * i + 1], DFT_R_e[2 * i] ), L_negate( Mpy_32_32( pDFT_L[2 * i], pDFT_R[2 * i + 1] ) ), add( DFT_L_e[2 * i], DFT_R_e[2 * i + 1] ), &xcorr_e[2 * i + 1] ); move32(); // pNrgL[i] = pDFT_L[2 * i] * pDFT_L[2 * i] + pDFT_L[2 * i + 1] * pDFT_L[2 * i + 1]; - pNrgL[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_L[2 * i] ), shl( DFT_L_e_tmp[2 * i], 1 ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_L[2 * i + 1] ), shl( DFT_L_e_tmp[2 * i + 1], 1 ), &pNrgL_e[i] ); + pNrgL[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_L[2 * i], pDFT_L[2 * i] ), shl( DFT_L_e[2 * i], 1 ), Mpy_32_32( pDFT_L[2 * i + 1], pDFT_L[2 * i + 1] ), shl( DFT_L_e[2 * i + 1], 1 ), &pNrgL_e[i] ); move32(); // pNrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; - pNrgR[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_R[2 * i], pDFT_R[2 * i] ), shl( DFT_R_e_tmp[2 * i], 1 ), Mpy_32_32( pDFT_R[2 * i + 1], pDFT_R[2 * i + 1] ), shl( DFT_R_e_tmp[2 * i + 1], 1 ), &pNrgR_e[i] ); + pNrgR[i] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( pDFT_R[2 * i], pDFT_R[2 * i] ), shl( DFT_R_e[2 * i], 1 ), Mpy_32_32( pDFT_R[2 * i + 1], pDFT_R[2 * i + 1] ), shl( DFT_R_e[2 * i + 1], 1 ), &pNrgR_e[i] ); move32(); /* Calculate L and R energy power spectrum */ Spd_L[i] = pNrgL[i]; @@ -2751,8 +2737,13 @@ void stereo_dft_enc_compute_itd_fx( den_cor_cur = BASOP_Util_Add_Mant32Exp( den_cor_cur, den_cor_cur_e, Mpy_32_32( xcorr_lb[i * XCORR_LB_BAND_WIDTH + j], xcorr_lb[i * XCORR_LB_BAND_WIDTH + j] ), shl( xcorr_lb_e[i * XCORR_LB_BAND_WIDTH + j], 1 ), &den_cor_cur_e ); // den_cor_prev += hItd->prev_xcorr_lb[i * XCORR_LB_BAND_WIDTH + j] * hItd->prev_xcorr_lb[i * XCORR_LB_BAND_WIDTH + j]; - den_cor_prev = BASOP_Util_Add_Mant32Exp( den_cor_prev, den_cor_prev_e, Mpy_32_32( hItd->prev_xcorr_lb_fx[i * XCORR_LB_BAND_WIDTH + j], hItd->prev_xcorr_lb_fx[i * XCORR_LB_BAND_WIDTH + j] ), - shl( hItd->prev_xcorr_lb_fx_e, 1 ), &den_cor_prev_e ); + tmp = hItd->prev_xcorr_lb_fx[i * XCORR_LB_BAND_WIDTH + j]; + move32(); + exp = norm_l( tmp ); + tmp = L_shl( tmp, exp ); + exp = sub( hItd->prev_xcorr_lb_fx_e, exp ); + den_cor_prev = BASOP_Util_Add_Mant32Exp( den_cor_prev, den_cor_prev_e, Mpy_32_32( tmp, tmp ), + shl( exp, 1 ), &den_cor_prev_e ); // if ( xcorr_lb[i * XCORR_LB_BAND_WIDTH + j] > xcorr_max ) IF( BASOP_Util_Cmp_Mant32Exp( xcorr_lb[i * XCORR_LB_BAND_WIDTH + j], xcorr_lb_e[i * XCORR_LB_BAND_WIDTH + j], xcorr_max, xcorr_max_e ) > 0 ) { diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index 255cdf1e528895daad16353bbe741657d67a3caa..a5b82fdd7efe8fa51acb88b857d7b1c4d37b6df0 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -124,9 +124,10 @@ void stereo_mdct_core_enc( { #ifdef IVAS_FLOAT_FIXED #ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING - Word32 *p_orig_spectrum_long_fx[CPE_CHANNELS], orig_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */ - Word32 *orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; /* Pointers to MDCT output for a short block (L/R) */ + Word32 *p_orig_spectrum_long_fx[CPE_CHANNELS]; #endif + Word32 orig_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */ + Word32 *orig_spectrum_fx[CPE_CHANNELS][NB_DIV]; /* Pointers to MDCT output for a short block (L/R) */ Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; Word32 *p_powerSpec_fx[CPE_CHANNELS]; #ifdef MSAN_FIX /*To be removed later*/ @@ -174,10 +175,8 @@ void stereo_mdct_core_enc( for ( ch = 0; ch < CPE_CHANNELS; ch++ ) { -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING orig_spectrum_fx[ch][0] = orig_spectrum_long_fx[ch]; orig_spectrum_fx[ch][1] = orig_spectrum_long_fx[ch] + N_TCX10_MAX; -#endif p_mdst_spectrum_long[ch] = mdst_spectrum_long[ch]; p_orig_spectrum_long[ch] = orig_spectrum_long[ch]; } @@ -444,11 +443,115 @@ void stereo_mdct_core_enc( #ifdef IVAS_FLOAT_FIXED p_powerSpec_fx[0] = powerSpec_fx[0]; p_powerSpec_fx[1] = powerSpec_fx[1]; + +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; + hIGFEnc[0] = sts[0]->hIGFEnc; + hIGFEnc[1] = sts[1]->hIGFEnc; + Word16 p_orig_spectrum_e[2]; + + Word16 igfGridIdx; + IF( sts[0]->last_core == ACELP_CORE && EQ_16( sts[0]->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_TRAN; + } + ELSE IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) + { + igfGridIdx = IGF_GRID_LB_NORM; + } + ELSE + { + /* It is short block */ + igfGridIdx = IGF_GRID_LB_SHORT; + } + f2me_buf( orig_spectrum[0][n], orig_spectrum_fx[0][n], &p_orig_spectrum_e[0], hIGFEnc[0]->infoStopLine ); + f2me_buf( orig_spectrum[1][n], orig_spectrum_fx[1][n], &p_orig_spectrum_e[1], hIGFEnc[1]->infoStopLine ); + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + Word16 *swb_offset; + hPrivateData = &hIGFEnc[ch]->igfData; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; + swb_offset = hGrid->swb_offset; + hIGFEnc[ch]->tns_predictionGain = float_to_fix16( hIGFEnc[ch]->tns_predictionGain_flt, Q23 ); + sts[ch]->hTcxEnc->spectrum_e[n] = 31 - Q_factor_arrL( sts[ch]->hTcxEnc->spectrum[n], hGrid->infoGranuleLen ); + sts[ch]->hTcxEnc->spectrum_e[n] = s_max( sts[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( &p_powerSpec[ch][0], hGrid->infoGranuleLen ) ); + sts[ch]->hTcxEnc->spectrum_e[n] = s_max( sts[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( inv_spectrum[ch][n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); + sts[ch]->hTcxEnc->spectrum_e[n] = s_max( sts[ch]->hTcxEnc->spectrum_e[n], 31 - Q_factor_arrL( powerSpecMsInv[ch][0], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); + floatToFixed_arr32( sts[ch]->hTcxEnc->spectrum[n], sts[ch]->hTcxEnc->spectrum_fx[n], 31 - sts[ch]->hTcxEnc->spectrum_e[n], hGrid->infoGranuleLen ); + floatToFixed_arr32( &p_powerSpec[ch][0], &p_powerSpec_fx[ch][0], 31 - sts[ch]->hTcxEnc->spectrum_e[n], hGrid->infoGranuleLen ); + floatToFixed_arr32( inv_spectrum[ch][n], inv_spectrum_fx[ch][n], 31 - sts[ch]->hTcxEnc->spectrum_e[n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); + floatToFixed_arr32( powerSpecMsInv[ch][0], powerSpecMsInv_fx[ch][0], 31 - sts[ch]->hTcxEnc->spectrum_e[n], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); + float max_sb = 0; + float max_tb = 0; + Word16 max_sb_fx = 0; + Word16 max_tb_fx = 0; + FOR( Word16 sfb = 0; sfb < 23; sfb++ ) + { + f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); + max_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_tb ); + max_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_tb ); + max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); + max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); + max_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_sb ); + max_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_sb ); + f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); + f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); + hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); + } + FOR( i = 0; i < IGF_MAX_TILES; i++ ) + { + hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ + hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ + FOR( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) + { + hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); + } + } + floatToFixed_arr16( &hGrid->whiteningThreshold_flt[0][0], &hGrid->whiteningThreshold[0][0], Q13, 2 * IGF_MAX_TILES ); + } +#endif /**********************************flt to fix ends here*******************************************************/ + hIGFEnc[0]->spec_be_igf_e = p_orig_spectrum_e[0]; + hIGFEnc[1]->spec_be_igf_e = p_orig_spectrum_e[1]; ProcessStereoIGF_fx( hStereoMdct, sts, ms_mask, -#ifndef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING orig_spectrum_fx, -#endif - p_powerSpec_fx, powerSpecMsInv_fx, inv_spectrum_fx, orig_spectrum, p_powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate ); + p_powerSpec_fx, powerSpecMsInv_fx, inv_spectrum_fx, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED /*************************************fix to flt conversion****************************************************/ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; + H_IGF_GRID hGrid; + hPrivateData = &hIGFEnc[ch]->igfData; + hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; + me2f_buf( sts[ch]->hTcxEnc->spectrum_fx[n], sts[ch]->hTcxEnc->spectrum_e[n], sts[ch]->hTcxEnc->spectrum[n], hGrid->infoGranuleLen ); + me2f_buf( &p_powerSpec_fx[ch][0], sts[ch]->hTcxEnc->spectrum_e[n], &p_powerSpec[ch][0], hGrid->infoGranuleLen ); + for ( Word16 sfb = 0; sfb < 23; sfb++ ) + { + hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); + hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); + hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); + } + for ( i = 0; i < IGF_MAX_TILES; i++ ) + { + hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ + hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ + for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) + { + hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); + } + } + } +#endif /**********************************fix to flt ends here*******************************************************/ #else ProcessStereoIGF( hStereoMdct, sts, ms_mask, orig_spectrum, p_powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); #endif // IVAS_FLOAT_FIXED diff --git a/lib_enc/lsf_enc_fx.c b/lib_enc/lsf_enc_fx.c index 121de20db6518a1b5ad86526bf1e91aa3b28793c..89f19c4645b98f8f13df8680f6933fddc921a2cc 100644 --- a/lib_enc/lsf_enc_fx.c +++ b/lib_enc/lsf_enc_fx.c @@ -2505,7 +2505,7 @@ static Word32 vq_lvq_lsf_enc_ivas_fx( /* LVQ quantization */ Vr_subt( lsf, cand[i], dd, M ); - mslvq_ivas_fx( dd, quant[i], lat_cv[i], idx_lead[i], idx_scale[i], w, mode, mode_glb, pred_flag ); + mslvq_ivas_16( dd, quant[i], lat_cv[i], idx_lead[i], idx_scale[i], w, mode, mode_glb, pred_flag ); Vr_add( cand[i], quant[i], cand[i], M ); /* arrange the LSF candidate vector prior to selection to an ascending order*/ diff --git a/lib_enc/mslvq_enc.c b/lib_enc/mslvq_enc.c index 48acd88f07df0d6164bdeb7d2c92761368435276..b15eacd1e708a426e9c42eb8a319c328fead2e11 100644 --- a/lib_enc/mslvq_enc.c +++ b/lib_enc/mslvq_enc.c @@ -38,6 +38,7 @@ #include "options.h" #include #include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "cnst.h" #include "wmc_auto.h" @@ -58,6 +59,7 @@ static UWord32 c2idx( const int16_t n, int16_t *p, const int16_t k ); static UWord32 encode_sign_pc1( const int16_t parity, float *cv ); static UWord32 encode_comb( float *cv, const int16_t idx_lead ); +Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead ); /*-----------------------------------------------------------------* * mslvq() @@ -173,8 +175,133 @@ float mslvq( return dist; } +#ifdef IVAS_FLOAT_FIXED +Word32 mslvq_ivas_16( + Word16 *pTmp, /* i : M-dimensional input vector */ + Word16 *quant, /* o : quantized vector */ + Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ + Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ + Word16 *idx_scale, /* o : scale index for each subvector */ + const Word16 *w, /* i : weights for LSF quantization */ + const Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ + const Word16 mode_glb, /* i : LVQ coding mode */ + const Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ + /*Retunr dist in q 22*/ +) +{ + Word32 dist, L_tmp; + const Word16 *p_scales, *p_sigma, *p_inv_sigma; + Word16 i, tmp, tmp1; + Word16 p_no_lead[MAX_NO_SCALES * 2]; + dist = L_deposit_l( 0 ); + IF( pred_flag == 0 ) + { + p_sigma = sigma_MSLVQ_fx[mode]; + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; + p_scales = scales_ivas_fx[mode_glb]; + + tmp = no_lead_idx[mode_glb][0]; + move16(); + tmp1 = no_lead_idx[mode_glb][1]; + move16(); + test(); + if ( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) + { + tmp = add( tmp, DELTA_LEADER ); + } + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) leaders_short[tmp][i]; + move16(); + p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; + move16(); + } + } + ELSE + { + IF( GE_16( pred_flag, 5 ) ) + { + /* assert( pred_flag >= 12 && pred_flag <= 15 ); */ + /* pred_flag is here the number of bits for MSLVQ */ + + p_sigma = &modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; + + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = &inv_modified_sigma_BWE_fx[mode_glb * LATTICE_DIM]; + IF( mode_glb == 0 ) + { + p_scales = &scales_BWE_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; + + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) no_lead_BWE[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; + move16(); + } + } + ELSE + { + p_scales = &scales_BWE_3b_fx_new[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) no_lead_BWE_3b[i + ( pred_flag - mslvq_SHB_min_bits[mode_glb] ) * 3]; + move16(); + } + } + } + ELSE + { + p_sigma = sigma_p_fx[mode]; + + /* inverse sigma is precomputed to save complexity */ + p_inv_sigma = inv_sigma_p_fx[mode]; + + p_scales = scales_p_ivas_fx[mode_glb]; + + tmp = no_lead_p_idx[mode_glb][0]; + move16(); + tmp1 = no_lead_p_idx[mode_glb][1]; + move16(); + + test(); + IF( LE_16( tmp, LIMIT_LEADER ) && LT_16( tmp, sub( tmp1, 2 ) ) ) + { + tmp = add( tmp, DELTA_LEADER ); + } + + test(); + IF( EQ_16( tmp, LIMIT_LEADER ) && ( tmp1 == 0 ) ) + { + tmp = add( tmp, DELTA_LEADER ); + tmp1 = add( tmp1, DELTA_LEADER ); + } + FOR( i = 0; i < MAX_NO_SCALES; i++ ) + { + p_no_lead[i] = (Word16) leaders_short[tmp][i]; + move16(); + p_no_lead[i + MAX_NO_SCALES] = (Word16) leaders_short[tmp1][i]; + move16(); + } + } + } + /* first subvector */ + dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, + p_sigma, p_inv_sigma, p_scales, p_no_lead ); + + IF( LT_16( pred_flag, 5 ) ) + { + /* second subvector */ + L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, p_no_lead + MAX_NO_SCALES ); + + dist = L_add( dist, L_tmp ); + } + + return dist; +} + +#endif /*-----------------------------------------------------------------* * q_data() * @@ -844,3 +971,49 @@ UWord32 index_lvq_SHB( return index; } + + +UWord32 index_lvq_SHB_fx( + const Word16 idx_lead, + const Word16 idx_scale, + const Word16 nbits, + Word16 *lat_cv, + const Word16 mode ) +{ + UWord16 i; + const Word8 *p_no_lead; + UWord32 index; + + IF( mode == 0 ) + { + p_no_lead = &no_lead_BWE[( nbits - mslvq_SHB_min_bits[0] ) * 3]; + } + ELSE + { + p_no_lead = &no_lead_BWE_3b[( nbits - mslvq_SHB_min_bits[1] ) * 3]; + } + + index = 0; + move32(); + IF( GT_16( idx_lead, -1 ) ) + { + index = 1; + move32(); + FOR( i = 0; i < idx_scale; i++ ) + { + index = index + table_no_cv[p_no_lead[i]]; + move32(); + } + + IF( idx_lead > 0 ) + { + index = index + table_no_cv[idx_lead]; + move32(); + } + + index = index + encode_comb_fx( lat_cv, idx_lead ); + move32(); + } + + return index; +} diff --git a/lib_enc/mslvq_enc_fx.c b/lib_enc/mslvq_enc_fx.c index c5a3e6bb753118c84a3f4e8bddd2e8086ba15877..b6445443bdf549b9e0775e347e3554317373a111 100644 --- a/lib_enc/mslvq_enc_fx.c +++ b/lib_enc/mslvq_enc_fx.c @@ -3,7 +3,6 @@ ====================================================================================*/ #include "cnst.h" -//#include "prot_fx.h" #include "rom_com_fx.h" #include "rom_com.h" #include "stl.h" @@ -18,7 +17,7 @@ *-----------------------------------------------------------------*/ static Word32 quantize_data_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, Word16 no_scales, const Word16 *no_lead ); -static Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead ); +Word32 quantize_data_ivas_fx( Word16 *data, const Word16 *w_in, Word16 *qin, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *sigma, const Word16 *inv_sigma, const Word16 *scales, const Word16 *no_lead ); static Word32 q_data_fx( Word16 *pTmp1, const Word16 *w1, Word16 *quant, Word16 *cv_out, Word16 *idx_lead, Word16 *idx_scale, const Word16 *p_sigma, const Word16 *p_inv_sigma, const Word16 *p_scales, Word16 *p_no_scales, const Word16 *p_no_lead ); static void prepare_data_fx( Word16 *xsort, Word16 *sign, Word16 *data, Word32 *w, const Word16 *w_in, const Word16 *sigma, const Word16 *inv_sigma, Word16 *p_sig ); static Word32 calculate_min_dist_fx( Word16 cv_pot[LATTICE_DIM], Word16 no_scales, const Word16 *scale, const Word32 *w, Word16 *p_best_scale, Word16 *p_best_idx, const Word16 *no_leaders, Word16 sig, Word16 *indx ); @@ -27,7 +26,7 @@ static void take_out_val_fx( Word16 *v, Word16 *v_out, Word16 val, Word16 len ); static Word16 index_leaders_fx( Word16 *cv, Word16 idx_lead, Word16 dim ); static Word16 c2idx_fx( Word16 n, Word16 *p, Word16 k ); static Word16 encode_sign_pc1_fx( Word16 parity, Word16 *cv ); -static Word32 encode_comb_fx( Word16 *cv, Word16 idx_lead ); +Word32 encode_comb_fx( Word16 *cv, Word16 idx_lead ); static void sort_desc_ind_fx( Word16 *s, Word16 len, Word16 *ind ); @@ -89,121 +88,7 @@ Word32 mslvq_fx( return dist; } -Word32 mslvq_ivas_fx( - Word16 *pTmp, /* i : M-dimensional input vector x2.56*/ - Word16 *quant, /* o : quantized vector x2.56*/ - Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) Q13*/ - Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ - Word16 *idx_scale, /* o : scale index for each subvector */ - Word16 *w, /* i : weights for LSF quantization Q10*/ - Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ - Word16 mode_glb, /* i : LVQ coding mode */ - Word16 pred_flag /* i : prediction flag (0: safety net, 1,2 - predictive )*/ -) -{ - Word32 dist, L_tmp; - const Word16 *p_scales, *p_sigma, *p_inv_sigma; - Word16 p_no_lead[MAX_NO_SCALES * 2]; - Word16 tmp, tmp1, i; - dist = L_deposit_l( 0 ); - move16(); - - IF( EQ_16( pred_flag, 0 ) ) - { - p_sigma = sigma_MSLVQ_fx[mode]; - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_MSLVQ_fx[mode]; - p_scales = scales_ivas_fx[mode_glb]; - tmp = no_lead_idx[mode_glb][0]; - tmp1 = no_lead_idx[mode_glb][1]; - IF( LE_16( tmp, LIMIT_LEADER ) && ( LT_16( tmp, sub( tmp1, 2 ) ) ) ) - { - tmp = add( tmp, DELTA_LEADER ); - } - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = leaders_short[tmp][i]; - p_no_lead[i + MAX_NO_SCALES] = leaders_short[tmp1][i]; - } - } - ELSE - { - IF( GE_16( pred_flag, 5 ) ) - { - /* assert( pred_flag >= 12 && pred_flag <= 15 ); */ - /* pred_flag is here the number of bits for MSLVQ */ - - p_sigma = &sigma_BWE16_fx[mode_glb * LATTICE_DIM]; - - /* inverse sigma is precomputed to save complexity */ -#if 1 // Pointing to wrong table, due to warning - p_inv_sigma = &sigma_BWE16_fx[mode_glb * LATTICE_DIM]; -#endif - - IF( EQ_16( mode_glb, 0 ) ) - { - p_scales = &scales_BWE_fx[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = no_lead_BWE[add( i, i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 ) )]; - } - } - ELSE - { - p_scales = &scales_BWE_3b_fx[i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 )]; - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = no_lead_BWE_3b[add( i, i_mult( sub( pred_flag, mslvq_SHB_min_bits[mode_glb] ), 3 ) )]; - } - } - } - ELSE - { - p_sigma = sigma_p_fx[mode]; - - /* inverse sigma is precomputed to save complexity */ - p_inv_sigma = inv_sigma_p_fx[mode]; - p_scales = scales_p_ivas_fx[mode_glb]; - - tmp = no_lead_p_idx[mode_glb][0]; - tmp1 = no_lead_p_idx[mode_glb][1]; - - IF( LE_16( tmp, LIMIT_LEADER ) && ( LT_16( tmp, sub( tmp1, 2 ) ) ) ) - { - tmp = add( tmp, DELTA_LEADER ); - } - - IF( EQ_16( tmp, LIMIT_LEADER ) && EQ_16( tmp1, 0 ) ) - { - tmp = add( tmp, DELTA_LEADER ); - tmp1 = add( tmp1, DELTA_LEADER ); - } - - FOR( i = 0; i < MAX_NO_SCALES; i++ ) - { - p_no_lead[i] = leaders_short[tmp][i]; - p_no_lead[i + MAX_NO_SCALES] = leaders_short[tmp1][i]; - } - } - } - - /* first subvector */ - dist = quantize_data_ivas_fx( pTmp, w, quant, cv_out, idx_lead, idx_scale, - p_sigma, p_inv_sigma, p_scales, p_no_lead ); - IF( LT_16( pred_flag, 5 ) ) - { - /* second subvector */ - L_tmp = quantize_data_ivas_fx( pTmp + LATTICE_DIM, w + LATTICE_DIM, quant + LATTICE_DIM, - cv_out + LATTICE_DIM, &idx_lead[1], &idx_scale[1], - p_sigma + LATTICE_DIM, p_inv_sigma + LATTICE_DIM, p_scales + MAX_NO_SCALES, - p_no_lead + MAX_NO_SCALES ); - - dist = L_add( dist, L_tmp ); - } - - return dist; -} /*-----------------------------------------------------------------* * q_data() * @@ -767,7 +652,7 @@ static Word32 quantize_data_fx( return min_dist; } -static Word32 quantize_data_ivas_fx( +Word32 quantize_data_ivas_fx( Word16 *data, /* i : residual LSF data to quantize x2.56*/ const Word16 *w_in, /* i : weights Q10*/ Word16 *qin, /* o : quantized output (scaled) x2.56*/ @@ -1029,9 +914,9 @@ void index_lvq_ivas_fx( * creates an index for the lattice codevector *-----------------------------------------------------------------*/ -static Word32 encode_comb_fx( /* o : index of the absolute valued codevector*/ - Word16 *cv, /* i : codevector to be indexed Q13*/ - Word16 idx_lead /* i : leader class index, to know the values */ +Word32 encode_comb_fx( /* o : index of the absolute valued codevector*/ + Word16 *cv, /* i : codevector to be indexed Q13*/ + Word16 idx_lead /* i : leader class index, to know the values */ ) { Word16 idx_sign, idx_ld_class; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index b1779369e14462324ac7693c9b3ad8c434ae24e3..6598d2f43be1a57263d5051f04830e04b9344851 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -3237,17 +3237,6 @@ Word32 mslvq_fx( Word16 pred_flag, /* i : prediction flag (0: safety net, 1 - predictive )*/ Word16 no_scales[][2] ); -Word32 mslvq_ivas_fx( - Word16 *pTmp, /* i : M-dimensional i vector */ - Word16 *quant, /* o : quantized vector */ - Word16 *cv_out, /* o : corresponding 8-dim lattice codevectors (without the scaling) */ - Word16 *idx_lead, /* o : leader index for each 8-dim subvector */ - Word16 *idx_scale, /* o : scale index for each subvector */ - Word16 *w, /* i : weights for LSF quantization */ - Word16 mode, /* i : number indicating the coding type (V/UV/G...)*/ - Word16 mode_glb, /* i : LVQ coding mode */ - Word16 pred_flag /* i : prediction flag (0: safety net, 1 - predictive )*/ -); Word16 multi_harm_fx( /* o : frame multi-harmonicity (1-harmonic, 0-not) */ const Word16 Bin_E[], /* i : log-energy spectrum of the current frame Q7 */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 677c94e04dea92b278d7b26780f1a15ccca60e56..13e0f4cafdfc05432f93bb24790134b0c619f912 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -2000,6 +2000,11 @@ Word16 ivas_smc_gmm_fx( temp32_log = L_add( BASOP_Util_Log2( *pFV_fx ), L_shl( sub( 31, Qfact_FV ), Q25 ) ); // Q25 temp32 = Mpy_32_32( temp32_log, bcox_lmbd_fx[i] ); // Q25 Word32 pow_temp = BASOP_util_Pow2( temp32, sub( 31, Q25 ), &pow_e ); + IF( pow_e <= 0 ) + { + pow_temp = L_shr( pow_temp, sub( 1, pow_e ) ); + pow_e = add( pow_e, sub( 1, pow_e ) ); + } temp32 = L_sub( pow_temp, L_shl( 1, 31 - pow_e ) ); temp_exp = 0; move32(); diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index 608d96d19f29249204e40279c78dd15418fc1076..fa64751348860272c44c241f534b7b3c42f1a5f8 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -39,6 +39,7 @@ #include #include "cnst.h" #include "prot.h" +#include "prot_fx.h" #include "rom_com.h" #include "rom_enc.h" #include "wmc_auto.h" @@ -73,7 +74,11 @@ static void gainFrSmooth_En( TD_BWE_ENC_HANDLE hBWE_TD, const int16_t last_extl, static void Quant_BWE_LSF( BSTR_ENC_HANDLE hBstr, TD_BWE_ENC_HANDLE hBWE_TD, const int16_t codec_mode, const float lsp_shb[], float Q_lsfs[], const int32_t extl_brate ); static void Quant_shb_ener_sf( Encoder_State *st, float *shb_ener_sf ); static void Quant_shb_res_gshape( Encoder_State *st, float *shb_res_gshape ); +#ifdef IVAS_FLOAT_FIXED +static void LVQQuant_BWE_LSF( BSTR_ENC_HANDLE hBstr, const Word16 lsf_shb_fx[], Word16 Q_lsfs_fx[], int16_t nbits ); +#else static void LVQQuant_BWE_LSF( BSTR_ENC_HANDLE hBstr, const float lsf_shb[], float Q_lsfs[], int16_t nbits ); +#endif /*-------------------------------------------------------------------* @@ -2003,7 +2008,381 @@ static void gainFrSmooth_En( * * Quantize super highband spectral envolope *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +#define MAXINT32 MAX_32 +static void first_VQstages_fx( + const Word16 *const *cb, + Word16 u[], /* i : vector to be encoded (prediction and mean removed) */ + Word16 *levels, /* i : number of levels in each stage */ + Word16 stagesVQ, /* i : number of stages */ + Word16 w[], /* i : weights */ + Word16 N, /* i : vector dimension */ + Word16 max_inner, /* i : maximum number of swaps in inner loop */ + Word16 indices_VQstage[] ) +{ + Word16 resid_buf[2 * LSFMBEST * M], *resid[2]; + Word32 dist_buf[2 * LSFMBEST], *dist[2], en; + Word32 f_tmp, L_tmp, L_tmp1, *pTmp32; + Word16 Tmp[M], *pTmp, cs; + Word16 *pTmp_short, idx_buf[2 * LSFMBEST * MAX_VQ_STAGES], parents[LSFMBEST], counter = 0, j, + m, s, c, c2, p_max, *indices[2]; + move16(); + Word16 maxC = LSFMBEST; + move16(); +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move16(); +#endif + + /*float dd[16];*/ + const Word16 *cb_stage, *cbp; + + /* Set pointers to previous (parent) and current node (parent node is indexed [0], current node is indexed [1]) */ + indices[0] = idx_buf; + move16(); + indices[1] = idx_buf + maxC * stagesVQ; + move16(); + resid[0] = resid_buf; + move16(); + resid[1] = resid_buf + maxC * N; + move16(); + dist[0] = dist_buf; + move16(); + dist[1] = dist_buf + maxC; + move16(); + + set16_fx( idx_buf, 0, ( const Word16 )( 2 * stagesVQ * maxC ) ); + set16_fx( parents, 0, maxC ); + + /* Set up inital distance vector */ + L_tmp = L_deposit_l( 0 ); + FOR( j = 0; j < N; j++ ) + { +#ifdef BASOP_NOGLOB + L_tmp1 = L_shl_o( L_mult0( u[j], w[j] ), 7, &Overflow ); /*x2.56 + Q8 + Q7 */ +#else /* BASOP_NOGLOB */ + L_tmp1 = L_shl( L_mult0( u[j], w[j] ), 7 ); /*x2.56 + Q8 + Q7 */ +#endif /* BASOP_NOGLOB */ + L_tmp1 = Mult_32_16( L_tmp1, u[j] ); /*x2.56 + Q15 + x2.56 -Q15 */ + L_tmp = L_add( L_tmp, L_tmp1 ); /*Q0 + x2.56 +x2.56 */ + } + set32_fx( dist[1], L_tmp, maxC ); + + /* Set up initial error (residual) vectors */ + pTmp = resid[1]; + move16(); + FOR( c = 0; c < maxC; c++ ) + { + Copy( u, pTmp, N ); + pTmp += N; + } + + /*----------------------------------------------------------------* + * LSF quantization + *----------------------------------------------------------------*/ + + /* Loop over all stages */ + m = 1; + move16(); + FOR( s = 0; s < stagesVQ; s++ ) + { + /* set codebook pointer to point to first stage */ + cbp = cb[s]; + + /* save pointer to the beginning of the current stage */ + cb_stage = cbp; + + /* swap pointers to parent and current nodes */ + pTmp_short = indices[0]; + indices[0] = indices[1]; + move16(); + indices[1] = pTmp_short; + move16(); + + pTmp = resid[0]; + resid[0] = resid[1]; + move16(); + resid[1] = pTmp; + move16(); + + pTmp32 = dist[0]; + dist[0] = dist[1]; + move32(); + dist[1] = pTmp32; + move32(); + + /* p_max points to maximum distortion node (worst of best) */ + p_max = 0; + move16(); + + /* set distortions to a large value */ + set32_fx( dist[1], MAXINT32, maxC ); + + FOR( j = 0; j < levels[s]; j++ ) + { + /* compute weighted codebook element and its energy */ + FOR( c2 = 0; c2 < N; c2++ ) + { + Tmp[c2] = shl( mult( w[c2], cbp[c2] ), 2 ); /* Q8 + x2.56 -Q15 +Q2 */ + move16(); + } + + en = L_mult( cbp[0], Tmp[0] ); + + FOR( c2 = 1; c2 < N; c2++ ) + { + en = L_mac( en, cbp[c2], Tmp[c2] ); /*x2.56 + x2.56 + Q-5 +Q1 */ + } + cbp += N; + move16(); + + /* iterate over all parent nodes */ + FOR( c = 0; c < m; c++ ) + { + pTmp = &resid[0][c * N]; + move16(); + L_tmp = L_mult( pTmp[0], Tmp[0] ); + FOR( c2 = 1; c2 < N; c2++ ) + { + L_tmp = L_mac( L_tmp, pTmp[c2], Tmp[c2] ); /* */ + } + + L_tmp = L_add( dist[0][c], L_sub( en, L_shl( L_tmp, 1 ) ) ); + + IF( LE_32( L_tmp, dist[1][p_max] ) ) + { + /* replace worst */ + dist[1][p_max] = L_tmp; + move32(); + indices[1][p_max * stagesVQ + s] = j; + move16(); + parents[p_max] = c; + move16(); + + /* limit number of times inner loop is entered */ + IF( LT_16( counter, max_inner ) ) + { + counter = add( counter, 1 ); + IF( LT_16( counter, max_inner ) ) + { + /* find new worst */ + p_max = maximum_32_fx( dist[1], maxC, &f_tmp ); + } + ELSE + { + /* find minimum distortion */ + p_max = minimum_32_fx( dist[1], maxC, &f_tmp ); + } + } + } + } + } + + /*------------------------------------------------------------* + * Compute error vectors for each node + *------------------------------------------------------------*/ + cs = 0; + move16(); + FOR( c = 0; c < maxC; c++ ) + { + /* subtract codebook entry from the residual vector of the parent node */ + pTmp = resid[1] + c * N; + move16(); + Copy( resid[0] + parents[c] * N, pTmp, N ); + Vr_subt( pTmp, cb_stage + ( indices[1][cs + s] ) * N, pTmp, N ); + + /* get indices that were used for parent node */ + Copy( indices[0] + parents[c] * stagesVQ, indices[1] + cs, s ); + cs = add( cs, stagesVQ ); + } + + m = maxC; + move16(); + } + + Copy( indices[1], indices_VQstage, maxC * stagesVQ ); + + return; +} +static Word16 dotp_loc( + const Word16 x[], /* i : vector x[] */ + const Word32 y[], /* i : vector y[] */ + const int16_t n /* i : vector length */ +) +{ + Word16 i; + Word32 suma; + Word16 guarded_bits = find_guarded_bits_fx( n ); + suma = L_shr( Mpy_32_16_1( y[0], x[0] ), guarded_bits ); + + FOR( i = 1; i < n; i++ ) + { + suma = L_add( suma, L_shr( Mpy_32_16_1( y[i], x[i] ), guarded_bits ) ); + } + suma = L_shl_sat( suma, guarded_bits ); + + return extract_h( suma ); +} +static void LVQQuant_BWE_LSF( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle*/ + const Word16 lsf_shb_fx[], /* i : unquanitzed LSFs */ + Word16 Q_lsfs_fx[], /* o : quanitzed LSFs */ + Word16 nbits ) +{ + + Word16 lsf_fx[LPC_SHB_ORDER]; + Word16 lsf_q_fx[LPC_SHB_ORDER]; + Word16 i, c2, dim1 = 6; + move16(); + Word16 levels[1], numbits_VQ; + Word16 c2_fx_temp; + + Word16 w_fx[8] = { 5120, 5120, 2048, 2048, 2048, 1024, 1024, 1024 }; // Q0 + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + Word16 cand_fx[LPC_SHB_ORDER], quant_fx[LPC_SHB_ORDER], e_fx[2], ftmp_fx; + const Word16 *cb_stage_fx; + Word16 indices_firstVQ[LSFMBEST]; + + Word16 Idx, idx_lead, idx_scale; + UWord32 LVQ_index; + Word16 dd_fx[LATTICE_DIM], cv_out_fx[LATTICE_DIM]; + Word16 bits_lvq, predictor_bits, empty_bits; + + empty_bits = 0; /* This is the difference to 21 bits, if we want lower number of bits */ + move16(); + nbits = sub( nbits, empty_bits ); /* THIS IS TO SIMULATE DIFFERENT NUMBER OF input BITS - should be removed */ + move16(); + c2 = sub( NUM_BITS_SHB_MSLVQ, nbits ); + move16(); + numbits_VQ = config_LSF_BWE[c2 * 3]; + move16(); + levels[0] = config_LSF_BWE[c2 * 3 + 1]; + move16(); + predictor_bits = config_LSF_BWE[c2 * 3 + 2]; + move16(); + IF( LT_16( nbits, 19 ) ) + { + cb_stage_fx = cb_LSF_BWE_fx[1]; + } + ELSE + { + cb_stage_fx = cb_LSF_BWE_fx[0]; + } + + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + lsf_fx[i] = sub( 16384, lsf_shb_fx[LPC_SHB_ORDER - 1 - i] ); + } + + /* remove mean */ + v_sub_16( lsf_fx, SHB_LSF_mean_fx, Q_lsfs_fx, LPC_SHB_ORDER ); + + /* 6D multi-stage 6bit coding */ + first_VQstages_fx( &cb_stage_fx, Q_lsfs_fx, levels, 1, w_fx, dim1, 3000, indices_firstVQ ); + + + /* 8D MSLVQ coding */ + bits_lvq = sub( sub( nbits, numbits_VQ ), predictor_bits ); + Copy( SHB_LSF_mean_fx, cand_fx, LPC_SHB_ORDER ); + + Idx = indices_firstVQ[0]; + + v_add_16( cand_fx, cb_stage_fx + Idx * dim1, cand_fx, dim1 ); + + /* LVQ quantization */ + Copy( cand_fx, quant_fx, LPC_SHB_ORDER ); + + v_sub_16( lsf_fx, cand_fx, dd_fx, LATTICE_DIM ); + + mslvq_ivas_16( dd_fx, quant_fx, cv_out_fx, &idx_lead, &idx_scale, w_fx, 0, ( nbits < 19 ), bits_lvq ); + + IF( EQ_16( idx_scale, -1 ) ) + { + set16_fx( cv_out_fx, 0, LATTICE_DIM ); + } + v_add_16( cand_fx, quant_fx, cand_fx, LATTICE_DIM ); + + /* arrange the LSF candidate vector prior to selection to an ascending order*/ + v_sort( cand_fx, 0, LPC_SHB_ORDER - 1 ); + + set16_fx( Q_lsfs_fx, 0, LPC_SHB_ORDER ); + /* mvr2r( mean_lsf, Q_lsfs, LPC_SHB_ORDER ); */ + + v_add_16( Q_lsfs_fx, cb_stage_fx + Idx * dim1, Q_lsfs_fx, dim1 ); + + /* write VQ indexes */ + push_indice( hBstr, IND_SHB_LSF, Idx, numbits_VQ ); + + /* write MSLVQ index */ + LVQ_index = index_lvq_SHB_fx( idx_lead, idx_scale, bits_lvq, cv_out_fx, ( nbits < 19 ) ); + + IF( GT_16( bits_lvq, 15 ) ) + { + push_indice( hBstr, IND_SHB_LSF, (Word16) ( ( LVQ_index ) & ( 0xffff >> 1 ) ), 15 ); + push_indice( hBstr, IND_SHB_LSF, (Word16) ( ( LVQ_index ) >> 15 ) & ( 0xffff >> 1 ), bits_lvq - 15 ); + } + ELSE + { + push_indice( hBstr, IND_SHB_LSF, (Word16) LVQ_index, bits_lvq ); + } + + v_add_16( Q_lsfs_fx, quant_fx, lsf_q_fx, LATTICE_DIM ); /* quantized mean removed data for first 8 dim*/ + + /* predict last 2 components */ + IF( predictor_bits == 0 ) + { + lsf_q_fx[LATTICE_DIM] = dotp_loc( lsf_q_fx, LastCoefPred_0bit_fx, LATTICE_DIM ); + lsf_q_fx[LATTICE_DIM + 1] = dotp_loc( lsf_q_fx, &LastCoefPred_0bit_fx[LATTICE_DIM + 1], LATTICE_DIM ); + } + ELSE + { + v_sub_16( &lsf_fx[LATTICE_DIM], &SHB_LSF_mean_fx[LATTICE_DIM], &lsf_q_fx[LATTICE_DIM], 2 ); + + FOR( i = 0; i < 2; i++ ) + { + ftmp_fx = dotp_loc( lsf_q_fx, &LastCoefPred_1bit_fx[2 * ( LATTICE_DIM + 1 ) * i], LATTICE_DIM ) - lsf_q_fx[LATTICE_DIM]; + + e_fx[i] = mult( ftmp_fx, ftmp_fx ); + + ftmp_fx = dotp_loc( lsf_q_fx, &LastCoefPred_1bit_fx[2 * ( LATTICE_DIM + 1 ) * i + LATTICE_DIM + 1], LATTICE_DIM ) - lsf_q_fx[LATTICE_DIM + 1]; + + e_fx[i] = add_sat( e_fx[i], mult( ftmp_fx, ftmp_fx ) ); + } + + c2_fx_temp = minimum_fx( e_fx, 2, &ftmp_fx ); + + lsf_q_fx[LATTICE_DIM] = dotp_loc( lsf_q_fx, &LastCoefPred_1bit_fx[2 * ( LATTICE_DIM + 1 ) * c2_fx_temp], LATTICE_DIM ); + + lsf_q_fx[LATTICE_DIM + 1] = dotp_loc( lsf_q_fx, &LastCoefPred_1bit_fx[2 * ( LATTICE_DIM + 1 ) * c2_fx_temp + LATTICE_DIM + 1], LATTICE_DIM ); + + push_indice( hBstr, IND_SHB_LSF, c2, 1 ); + } + + if ( empty_bits > 0 ) + { + push_indice( hBstr, IND_SHB_LSF, 0, empty_bits ); + } + + v_add_16( SHB_LSF_mean_fx, lsf_q_fx, lsf_q_fx, LPC_SHB_ORDER ); + + v_sort( lsf_q_fx, 0, LPC_SHB_ORDER - 1 ); + + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + Q_lsfs_fx[i] = sub_sat( 16384, lsf_q_fx[LPC_SHB_ORDER - 1 - i] ); + } + + return; +} +#else static void LVQQuant_BWE_LSF( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle*/ const float lsf_shb[], /* i : unquanitzed LSFs */ @@ -2140,6 +2519,7 @@ static void LVQQuant_BWE_LSF( return; } +#endif /*-------------------------------------------------------------------* * Quant_BWE_LSF() * @@ -2165,7 +2545,25 @@ static void Quant_BWE_LSF( if ( extl_brate == SWB_TBE_1k75 ) { + +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 lsf_shb_fx[LPC_SHB_ORDER]; + for ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + lsf_shb_fx[i] = (Word16) ( lsf_shb[i] * 32767 ); + } +#endif + LVQQuant_BWE_LSF( hBstr, lsf_shb_fx, lsf_shb_fx, NUM_BITS_SHB_MSLVQ ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < LPC_SHB_ORDER; i++ ) + { + Q_lsfs[i] = (float) ( (float) lsf_shb_fx[i] / 32767.0 ); + } +#endif +#else LVQQuant_BWE_LSF( hBstr, lsf_shb, Q_lsfs, NUM_BITS_SHB_MSLVQ ); +#endif } else { diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index 8c21f3f58945acc1f4d0b8377dd46d31a7d2f3fe..a8937b4889b69fcea91bc111d2e220672effa503 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -46,6 +46,8 @@ #include "wmc_auto.h" #include "ivas_prot.h" +#define ONE_POINT_ONE_FIVE_Q7 147 +#define ONE_POINT_ONE_FIVE_Q23 9646899 /*---------------------------------------------------------------------* * ComputeSpectrumNoiseMeasure() * @@ -1586,171 +1588,97 @@ void ProcessIGF( #ifdef IVAS_FLOAT_FIXED void ProcessStereoIGF_fx( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, - Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ - int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ -#if 1 + Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ + Word16 ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ + Word32 *pITFMDCTSpectrum_fx[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ Word32 *pPowerSpectrum_fx[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ Word32 *pPowerSpectrumMsInv_fx[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ -#endif - float *pITFMDCTSpectrum[CPE_CHANNELS][NB_DIV], /* i : MDCT spectrum fir ITF */ - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ - float *pPowerSpectrumMsInv[CPE_CHANNELS][NB_DIV], /* i : inverse power spectrum */ - float *inv_spectrum[CPE_CHANNELS][NB_DIV], /* i : inverse spectrum */ - const int16_t frameno, /* i : flag indicating index of current subfr. */ - const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ - const int32_t element_brate /* i : element bitrate */ + const Word16 frameno, /* i : flag indicating index of current subfr. */ + const Word16 sp_aud_decision0, /* i : sp_aud_decision0 */ + const Word32 element_brate /* i : element bitrate */ ) { - int16_t ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; - float predictionGain; - float A[ITF_MAX_FILTER_ORDER + 1]; + Word16 ch, igfGridIdx, isIndepFlag, bsBits, pBsStart, curr_order; + Word16 predictionGain; + Word16 A[ITF_MAX_FILTER_ORDER + 1]; + Word16 Q_A; IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS]; BSTR_ENC_HANDLE hBstr; - hIGFEnc[0] = sts[0]->hIGFEnc; hIGFEnc[1] = sts[1]->hIGFEnc; isIndepFlag = 1; + move16(); - if ( sts[0]->last_core == ACELP_CORE && sts[0]->core == TCX_20_CORE ) + test(); + IF( sts[0]->last_core == ACELP_CORE && EQ_16( sts[0]->core, TCX_20_CORE ) ) { igfGridIdx = IGF_GRID_LB_TRAN; } - else if ( sts[0]->core == TCX_20_CORE ) + ELSE IF( EQ_16( sts[0]->core, TCX_20_CORE ) ) { igfGridIdx = IGF_GRID_LB_NORM; } - else + ELSE { /* It is short block */ igfGridIdx = IGF_GRID_LB_SHORT; - if ( frameno == 1 ) + if ( EQ_16( frameno, 1 ) ) { isIndepFlag = 0; + move16(); } } + move16(); - IGFSaveSpectrumForITF( hIGFEnc[0], igfGridIdx, pITFMDCTSpectrum[0][frameno] ); + IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[0], igfGridIdx, pITFMDCTSpectrum_fx[0][frameno] ); + + IGFSaveSpectrumForITF_ivas_fx( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum_fx[1][frameno] ); - IGFSaveSpectrumForITF( hIGFEnc[1], igfGridIdx, pITFMDCTSpectrum[1][frameno] ); -#if 1 /*************************************flt to fix conversion****************************************************/ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - H_IGF_GRID hGrid; - Word16 *swb_offset; - hPrivateData = &hIGFEnc[ch]->igfData; - hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; - swb_offset = hGrid->swb_offset; - sts[ch]->hTcxEnc->spectrum_e[frameno] = 31 - Q_factor_arrL( sts[ch]->hTcxEnc->spectrum[frameno], hGrid->infoGranuleLen ); - sts[ch]->hTcxEnc->spectrum_e[frameno] = s_max( sts[ch]->hTcxEnc->spectrum_e[frameno], 31 - Q_factor_arrL( &pPowerSpectrum[ch][0], hGrid->infoGranuleLen ) ); - sts[ch]->hTcxEnc->spectrum_e[frameno] = s_max( sts[ch]->hTcxEnc->spectrum_e[frameno], 31 - Q_factor_arrL( inv_spectrum[ch][frameno], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); - sts[ch]->hTcxEnc->spectrum_e[frameno] = s_max( sts[ch]->hTcxEnc->spectrum_e[frameno], 31 - Q_factor_arrL( pPowerSpectrumMsInv[ch][0], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ) ); - floatToFixed_arr32( sts[ch]->hTcxEnc->spectrum[frameno], sts[ch]->hTcxEnc->spectrum_fx[frameno], 31 - sts[ch]->hTcxEnc->spectrum_e[frameno], hGrid->infoGranuleLen ); - floatToFixed_arr32( &pPowerSpectrum[ch][0], &pPowerSpectrum_fx[ch][0], 31 - sts[ch]->hTcxEnc->spectrum_e[frameno], hGrid->infoGranuleLen ); - floatToFixed_arr32( inv_spectrum[ch][frameno], inv_spectrum_fx[ch][frameno], 31 - sts[ch]->hTcxEnc->spectrum_e[frameno], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); - floatToFixed_arr32( pPowerSpectrumMsInv[ch][0], pPowerSpectrumMsInv_fx[ch][0], 31 - sts[ch]->hTcxEnc->spectrum_e[frameno], swb_offset[hGrid->sfbWrap[hGrid->nTiles]] ); - float max_sb = 0; - float max_tb = 0; - Word16 max_sb_fx = 0; - Word16 max_tb_fx = 0; - for ( Word16 sfb = 0; sfb < 23; sfb++ ) - { - f2me_16( hPrivateData->prevDampingFactor_IIR[sfb], &hPrivateData->prevDampingFactor_IIR_fx[sfb], &hPrivateData->prevDampingFactor_IIR_e[sfb] ); - max_tb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_TB[sfb] ), max_tb ); - max_tb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_TB[sfb] ), max_tb ); - max_tb = max( fabsf( hPrivateData->SFM_tb[sfb] ), max_tb ); - max_sb = max( fabsf( hPrivateData->SFM_sb[sfb] ), max_sb ); - max_sb = max( fabsf( hPrivateData->prevSFM_FIR_SFB_SB[sfb] ), max_sb ); - max_sb = max( fabsf( hPrivateData->prevSFM_IIR_SFB_SB[sfb] ), max_sb ); - f2me_16( max_tb, &max_tb_fx, &hPrivateData->sfb_tb_e[sfb] ); - f2me_16( max_sb, &max_sb_fx, &hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_TB[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_FIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb] = float_to_fix16( hPrivateData->prevSFM_IIR_SFB_SB[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - hPrivateData->SFM_tb_fx[sfb] = float_to_fix16( hPrivateData->SFM_tb[sfb], sub( 15, hPrivateData->sfb_tb_e[sfb] ) ); - hPrivateData->SFM_sb_fx[sfb] = float_to_fix16( hPrivateData->SFM_sb[sfb], sub( 15, hPrivateData->sfb_sb_e[sfb] ) ); - } - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR[i] = float_to_fix( hPrivateData->prevSFM_FIR_flt[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR[i] = float_to_fix16( hPrivateData->prevSFM_IIR_flt[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM_fx[i][j] = float_to_fix16( hPrivateData->igfPastSFM[i][j], 13 ); - } - } - floatToFixed_arr16( &hGrid->whiteningThreshold_flt[0][0], &hGrid->whiteningThreshold[0][0], Q13, 2 * IGF_MAX_TILES ); - } -#endif /**********************************flt to fix ends here*******************************************************/ IGFEncApplyStereo_fx( hStereoMdct, ms_mask, hIGFEnc, igfGridIdx, sts, pPowerSpectrum_fx, pPowerSpectrumMsInv_fx, inv_spectrum_fx, frameno, sp_aud_decision0, element_brate ); -#if 1 /*************************************fix to flt conversion****************************************************/ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData; - H_IGF_GRID hGrid; - hPrivateData = &hIGFEnc[ch]->igfData; - hGrid = &hPrivateData->igfInfo.grid[(Word16) igfGridIdx]; - me2f_buf( sts[ch]->hTcxEnc->spectrum_fx[frameno], sts[ch]->hTcxEnc->spectrum_e[frameno], sts[ch]->hTcxEnc->spectrum[frameno], hGrid->infoGranuleLen ); - me2f_buf( &pPowerSpectrum_fx[ch][0], sts[ch]->hTcxEnc->spectrum_e[frameno], &pPowerSpectrum[ch][0], hGrid->infoGranuleLen ); - for ( Word16 sfb = 0; sfb < 23; sfb++ ) - { - hPrivateData->prevSFM_FIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_TB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_TB_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->prevSFM_FIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_FIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevSFM_IIR_SFB_SB[sfb] = me2f_16( hPrivateData->prevSFM_IIR_SFB_SB_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->SFM_tb[sfb] = me2f_16( hPrivateData->SFM_tb_fx[sfb], hPrivateData->sfb_tb_e[sfb] ); - hPrivateData->SFM_sb[sfb] = me2f_16( hPrivateData->SFM_sb_fx[sfb], hPrivateData->sfb_sb_e[sfb] ); - hPrivateData->prevDampingFactor_IIR[sfb] = me2f_16( hPrivateData->prevDampingFactor_IIR_fx[sfb], hPrivateData->prevDampingFactor_IIR_e[sfb] ); - } - for ( int i = 0; i < IGF_MAX_TILES; i++ ) - { - hPrivateData->prevSFM_FIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_FIR[i], 16 ); /*15Q16*/ - hPrivateData->prevSFM_IIR_flt[i] = fixedToFloat( hPrivateData->prevSFM_IIR[i], 13 ); /*2Q13*/ - for ( int j = 0; j < IGF_PAST_SFM_LEN; j++ ) - { - hPrivateData->igfPastSFM[i][j] = fixedToFloat( hPrivateData->igfPastSFM_fx[i][j], 13 ); - } - } - } -#endif /**********************************fix to flt ends here*******************************************************/ - for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) { curr_order = 0; + move16(); - ITF_Detect( hIGFEnc[ch]->spec_be_igf_flt, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &predictionGain, &curr_order ); + Q_A = 0; + move16(); - hIGFEnc[ch]->flatteningTrigger = hIGFEnc[ch]->tns_predictionGain_flt < 1.15 && predictionGain < 1.15; + ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); + + test(); + hIGFEnc[ch]->flatteningTrigger = LT_32( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q23 ) && LT_32( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); + move16(); hIGFEnc[ch]->infoTotalBitsPerFrameWritten = 0; + move16(); - if ( sts[ch]->core == TCX_20_CORE ) + IF( EQ_16( sts[ch]->core, TCX_20_CORE ) ) { IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], NULL, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); } - else + ELSE { hBstr = sts[ch]->hBstr; pBsStart = hBstr->nb_ind_tot; + move16(); + if ( ch > 0 ) { hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot; } IGFEncWriteBitstream_ivas_fx( hIGFEnc[ch], hBstr, &hIGFEnc[ch]->infoTotalBitsPerFrameWritten, igfGridIdx, isIndepFlag ); - bsBits = hBstr->nb_ind_tot - pBsStart; + bsBits = sub( hBstr->nb_ind_tot, pBsStart ); IGFEncConcatenateBitstream( hIGFEnc[ch], bsBits, hBstr ); } } - return; } #endif - void ProcessStereoIGF( STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index f4a8b359454062e04a6a95f36aeba409385e0a96..472e70a26e8f7edfd4361ba6d0d56f22bd1c1734 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -5362,7 +5362,9 @@ static void matrixMul_fx( Word16 chA, chB; Word16 min_q_shift1, min_q_shift2; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); +#ifndef IVAS_ENH64_CADENCE_CHANGES Word32 tmp1, tmp2; +#endif min_q_shift1 = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); min_q_shift2 = sub( s_min( L_norm_arr( Bre_fx[0], size ), L_norm_arr( Bim_fx[0], size ) ), 1 ); @@ -5669,7 +5671,9 @@ static void matrixTransp2Mul_fx( Word16 chA, chB; Word16 min_q_shift; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); +#ifndef IVAS_ENH64_CADENCE_CHANGES Word32 tmp1, tmp2; +#endif min_q_shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); scale_sig32( Are_fx[0], size, min_q_shift );