diff --git a/lib_com/edct_fx.c b/lib_com/edct_fx.c index 4b628e7d6dd3fed9c4eec459b8e4caace1c22b2a..1d1710a1b0fc33dffaca65c2f1371255f1a29793 100644 --- a/lib_com/edct_fx.c +++ b/lib_com/edct_fx.c @@ -646,7 +646,7 @@ void edxt_fx( IF( EQ_16( kernelType, MDST_II ) || EQ_16( kernelType, MDCT_II ) ) { const Word16 Nm1 = sub( length, 1 ); - const Word16 xSign = sub( kernelType, 1 ); + const Word16 xSign = 2 * ( kernelType >> 1 ) - 1; Word32 re[L_FRAME_PLUS]; Word32 im[L_FRAME_PLUS]; @@ -655,7 +655,7 @@ void edxt_fx( FOR( k = shr( Nm1, 1 ); k >= 0; k-- ) /* pre-modulation of audio input */ { re[k] = x[2 * k]; - re[Nm1 - k] = Mpy_32_16_1( x[2 * k + 1], xSign ); + re[Nm1 - k] = Mpy_32_16_1( x[2 * k + 1], shl_sat(xSign, 15) ); im[k] = im[Nm1 - k] = 0; } @@ -752,7 +752,7 @@ void edxt_fx( y[2 * k] = re[k]; IF( NE_16( xSign, 0 ) ) { - y[2 * k + 1] = re[sub( Nm1, k )]; + y[2 * k + 1] = Mpy_32_16_1(re[sub( Nm1, k )], shl_sat(xSign, 15)); } ELSE { diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6a5e2718856d6fb55f84f89287cd585cad31d090..0a96208f473c97bf5aeacc1ce5f77594aefd3896 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1296,16 +1296,19 @@ void decoder_tcx_imdct_fx( const int16_t L_frame, const int16_t L_frameTCX, const int16_t left_rect, - float x[N_MAX], - float xn_buf[], + Word32 x_fx[N_MAX], + Word16 q_x, + Word16 xn_buf_fx[], + Word16 q_win, const uint16_t kernelType, /* i : TCX transform kernel type */ const int16_t fUseTns, /* i : flag that is set if TNS data is present */ - float synth[], /* i/o: synth[-M..L_frame] */ - float synthFB[], + Word16 synth_fx[], /* i/o: synth[-M..L_frame] */ + Word16 synthFB_fx[], const int16_t bfi, /* i : Bad frame indicator */ const int16_t frame_cnt, /* i : frame counter in the super frame */ const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ); + void ivas_sba_dirac_stereo_dec_fx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ Word32 *output[CPE_CHANNELS], /* i/o: output synthesis signal */ diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind.c index 0f7db34b521290fb49d12897d3f107b468f4012d..f22c4d6a6f51c30e0762a55663a7c76fdbb511ea 100644 --- a/lib_com/lag_wind.c +++ b/lib_com/lag_wind.c @@ -237,6 +237,60 @@ void lag_wind( } +void lag_wind_32( + Word32 r[], /* in/out: autocorrelations */ + Word16 m, /* input : order of LP filter */ + Word32 sr_core, /* input : sampling rate */ + Word16 strength /* input : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */ +) +{ + Word16 i; + Word32 tmp; + const Word32* wnd; + + + assert(0 <= strength && strength <= NUM_LAGW_STRENGTHS); + SWITCH(sr_core) + { + case 8000: + assert(m <= 16); + assert(strength == LAGW_STRONG); + wnd = lag_window_8k_32; + BREAK; + case 12800: + assert(m <= 16); + wnd = lag_window_12k8_32[strength]; + BREAK; + case 16000: + assert(m <= 16); + wnd = lag_window_16k_32[strength]; + BREAK; + case 24000: + case 25600: + assert(m <= 16); + wnd = lag_window_25k6_32[strength]; + BREAK; + case 32000: + assert(m <= 16); + wnd = lag_window_32k_32[strength]; + BREAK; + case 48000: + assert(m <= 16); + assert(strength == LAGW_STRONG); + wnd = lag_window_48k_32; + BREAK; + default: + assert(!"Lag window not implemented for this sampling rate"); + return; + } + + FOR(i = 1; i <= m; i++) + { + r[i] = Mpy_32_32(r[i], wnd[i - 1]); + } + +} + void adapt_lag_wind( Word16 r_h[], /* in/out: autocorrelations */ Word16 r_l[], /* in/out: autocorrelations */ diff --git a/lib_com/lpc_tools.c b/lib_com/lpc_tools.c index 2fefb9fc1341108f8e3adf0c289fc8f59fa65e59..41047857976e83f0dde36d799505ab0b2160ac82 100644 --- a/lib_com/lpc_tools.c +++ b/lib_com/lpc_tools.c @@ -192,6 +192,78 @@ int16_t lev_dur( return ( flag ); } +#ifdef IVAS_FLOAT_FIXED +Word16 lev_dur_fx( + Word32 *a_fx, /* o : LP coefficients (a[0] = 1.0) */ + const Word32 *r_fx, /* i : vector of autocorrelations */ + const Word16 m, /* i : order of LP filter */ + Word32 epsP[], /* o : prediction error energy */ + Word16 q_a, + Word16 q_r +) +{ + Word16 i, j, l; + Word16 buf_fx[TCXLTP_LTP_ORDER]; + Word16 *rc_fx; /* reflection coefficients 0,...,m-1 */ + Word32 at; + Word32 s, err; + Word16 flag = 0; + + rc_fx = &buf_fx[0]; + rc_fx[0] = divide3232( L_negate(r_fx[1]), r_fx[0]); //Q(31) + a_fx[0] = L_shl(1, q_a); + a_fx[1] = L_shl(rc_fx[0], sub(q_a, 15)); + err = L_add(r_fx[0], Mpy_32_16_1(r_fx[1], rc_fx[0])); // Q(q_r) + IF ( epsP != NULL ) + { + epsP[0] = r_fx[0]; + move32(); + epsP[1] = err; + move32(); + } + + FOR ( i = 2; i <= m; i++ ) + { + s = 0; // Q(q_a + q_r - 31) + FOR ( j = 0; j < i; j++ ) + { + s = L_add(s, Mpy_32_32(r_fx[i - j], a_fx[j])); + } + + rc_fx[i - 1] = divide3232( L_negate( s ), L_shr(err, sub(31, q_a))); + + IF ( abs_s( rc_fx[i - 1] ) > 32749 ) // 32749 = 0.99945 in Q15 + { + flag = 1; /* Test for unstable filter. If unstable keep old A(z) */ + } + + FOR ( j = 1; j <= shr(i, 1); j++ ) + { + l = sub(i, j); + at = L_add(a_fx[j], Mpy_32_16_1(a_fx[l], rc_fx[i - 1])); // Q(q_a) + a_fx[l] = L_add(a_fx[l], Mpy_32_16_1(a_fx[j], rc_fx[i - 1])); + a_fx[j] = at; + move32(); + } + + a_fx[i] = L_shl(rc_fx[i - 1], sub(q_a, 15)); + + err = L_add(err, L_shl(Mpy_32_16_1(s, rc_fx[i - 1]), sub(31, q_a))); // q_err - q_s + IF ( LE_32(err, 0) ) + { + err = L_shr(327, 31 - q_r); // 327 = 0.01 in Q15 + } + + IF ( epsP != NULL ) + { + epsP[i] = err; + move32(); + } + } + + return ( flag ); +} +#endif /*---------------------------------------------------------------------* diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index 92230ff26f8aa42a0e23271ab55047c5ad30caed..1733137c744dc38fab9d76c2883bfd455a5c9832 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -164,6 +164,114 @@ void autocorr_fx( *Q_r = sub(norm, shl(shift, 1)); move16(); } +#ifdef IVAS_FLOAT_FIXED +void autocorr_fx_32( + const Word16 x[], /* i : Input signal */ + const Word16 m, /* i : LPC order Q0 */ + Word32 r[], /* o : Autocorrelations (msb) */ + Word16 *Q_r, /* o : normalisation shift of r Q0 */ + const Word16 len, /* i : Frame lenght */ + const Word16* wind, /* i : Window used */ + Word16 rev_flag, + const Word16 sym_flag /* i : symmetric window flag */ +) +{ + Word16 i, j, norm, shift, y[MAX_LEN_LP]; + Word16 fact; + Word32 L_sum, L_tmp; + + IF(EQ_16(rev_flag,1)) + { + /* Windowing of signal */ + FOR (i = 0; i < len; i++) + { + y[i] = mult_r(x[i], wind[len-i-1]); + move16(); + } + } + ELSE IF( EQ_16(sym_flag,1)) + { + /* symmetric window of even length */ + FOR( i=0; i 0) + { + fact = lshr(-32768, shift); + FOR (i = 0; i < len; i++) + { + y[i] = mult_r(y[i], fact); + move16(); + } + } + ELSE + { + shift = 0; + move16(); + } + + /* Compute and normalize r[0] */ + L_sum = L_mac(1, y[0], y[0]); + FOR (i = 1; i < len; i++) + { + L_sum = L_mac(L_sum, y[i], y[i]); + } + norm = norm_l(L_sum); + L_sum = L_shl(L_sum, norm); + r[0] = L_sum; + move32(); + + /* Compute r[1] to r[m] */ + FOR (i = 1; i <= m; i++) + { + L_sum = L_mult(y[0],y[i]); + FOR (j = 1; j < len - i; j++) + { + L_sum = L_mac(L_sum, y[j], y[j + i]); + } + + L_sum = L_shl(L_sum, norm); + r[i] = L_sum; + move32(); + } + + *Q_r = sub(norm, shl(shift, 1)); + move16(); +} +#endif /***************************************************************************** * * diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 985e88b9cb72ec6b715b850a9c0f8ca70a1bea49..278efc10b4a29fc94122959c1609d3eca836ad17 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -955,6 +955,17 @@ void autocorr_fx( const Word16 sym_flag /* i : symmetric window flag */ ); +void autocorr_fx_32( + const Word16 x[], /* i : Input signal */ + const Word16 m, /* i : LPC order Q0 */ + Word32 r[], /* o : Autocorrelations (msb) */ + Word16 *Q_r, /* o : normalisation shift of r Q0 */ + const Word16 len, /* i : Frame lenght */ + const Word16* wind, /* i : Window used */ + Word16 rev_flag, + const Word16 sym_flag /* i : symmetric window flag */ +); + Word16 E_LPC_lev_dur(const Word16 Rh[], const Word16 Rl[], Word16 A[], Word32 epsP[], const Word16 order, Word16 *parcorr ); @@ -971,6 +982,15 @@ Word16 E_LPC_lev_dur_stab_fx(const Word16 Rh[], const Word16 Rl[], Word32 A[], Word32 *mem, Word16 k_max ); +Word16 lev_dur_fx( + Word32 *a_fx, /* o : LP coefficients (a[0] = 1.0) */ + const Word32 *r_fx, /* i : vector of autocorrelations */ + const Word16 m, /* i : order of LP filter */ + Word32 epsP[], /* o : prediction error energy */ + Word16 q_a, + Word16 q_r +); + void E_LPC_a_add_tilt(const Word16 *a, Word16 *ap, Word16 gamma, Word16 m); void E_LPC_int_lpc_tcx(const Word16 lsp_old[], /* i : LSPs from past frame (1Q14) */ const Word16 lsp_new[], /* i : LSPs from present frame (1Q14) */ @@ -2329,6 +2349,13 @@ void lag_wind( Word16 strength /* i : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */ ); +void lag_wind_32( + Word32 r[], /* in/out: autocorrelations */ + Word16 m, /* input : order of LP filter */ + Word32 sr_core, /* input : sampling rate */ + Word16 strength /* input : LAGW_WEAK, LAGW_MEDIUM, or LAGW_STRONG */ +); + //preemp_fx.c #define preemph_fx(signal,mu,L,mem) preemph_copy_fx((signal),(signal),(mu),(L),(mem)) @@ -5233,6 +5260,8 @@ Word32 mul_sbc_14bits(Word32 r, Word16 c); //window.c void ham_cos_window(Word16 *fh, const Word16 n1, const Word16 n2); +void ham_cos_window_ivas(Word16 *fh, const Word16 n1, const Word16 n2); + //arith_coder_fx.c Word32 expfp( /* o: Q31 */ const Word16 x, /* i: mantissa Q-e */ @@ -5409,6 +5438,13 @@ void v_multc_fixed_16( const Word16 N /* i : Vector length */ ); +void v_multc_fixed_16_16( + const Word16 x[], /* i : Input vector */ + const Word16 c, /* i : Constant */ + Word16 y[], /* o : Output vector that contains c*x */ + const Word16 N /* i : Vector length */ +); + void v_add_fixed( const Word32 x1[], /* i : Input vector 1 */ const Word32 x2[], /* i : Input vector 2 */ @@ -8759,6 +8795,37 @@ void Interpolate_allpass_steep_32( void IMDCT( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_TDAC, Word16 *xn_buf, const Word16 *tcx_aldo_window_1, const PWord16 *tcx_aldo_window_1_trunc, const PWord16 *tcx_aldo_window_2, const PWord16 *tcx_mdct_window_half, const PWord16 *tcx_mdct_window_minimum, const PWord16 *tcx_mdct_window_trans, Word16 tcx_mdct_window_half_length, Word16 tcx_mdct_window_min_length, Word16 index, Word16 left_rect, Word16 tcx_offset, Word16 overlap, Word16 L_frame, Word16 L_frameTCX, Word16 L_spec_TCX5, Word16 L_frame_glob, Word16 frame_cnt, Word16 bfi, Word16 *old_out, Word16 *Q_old_wtda, Decoder_State *st, Word16 fullbandScale, Word16 *acelp_zir ); +void IMDCT_ivas_fx( + Word32 *x_fx, + Word16 q_x, + Word16 *old_syn_overl_fx, + Word16 *syn_Overl_TDAC_fx, + Word16 *xn_buf_fx, + const Word16 *tcx_aldo_window_1_fx, + const PWord16 *tcx_aldo_window_1_trunc_fx, + const PWord16 *tcx_aldo_window_2_fx, + const PWord16 *tcx_mdct_window_half_fx, + const PWord16 *tcx_mdct_window_minimum_fx, + const PWord16 *tcx_mdct_window_trans_fx, + const Word16 tcx_mdct_window_half_length, + const Word16 tcx_mdct_window_min_length, + Word16 index, + const UWord16 kernel_type, /* i : TCX transform kernel type */ + const Word16 left_rect, + const Word16 tcx_offset, + const Word16 overlap, + const Word16 L_frame, + const Word16 L_frameTCX, + const Word16 L_spec_TCX5, + const Word16 L_frame_glob, + const Word16 frame_cnt, + const Word16 bfi, + Word16 *old_out_fx, + const Word16 FB_flag, + Decoder_State *st, + const Word16 fullbandScale, + Word16 *acelp_zir_fx); + void v_mult16_fixed( const Word16 x1[], /* i : Input vector 1 */ const Word16 x2[], /* i : Input vector 2 */ diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 0fe05112e686622c7dd0e1c2c600ccc870567f11..43da3fc64512023769eeaa1bc82a71b624dbff69 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -1274,6 +1274,77 @@ const Word16 lag_window_48k[2][16] = /* LAGW_STRONG */ /* l */ { 23360, 22272, 20672, 18304, 15360, 11904, 8000, 3648, 31808, 27008, 22080, 17280, 12608, 8256, 4480, 1344 } }; +/* 32 bit declarations */ +const Word32 lag_window_8k_32[16] = /* LAGW_STRONG */ +{ + 2144886016, 2137753344, 2125918208, 2109458944, 2088484096, 2063131264, 2033565312, 1999976832, 1962579968, 1921610496, 1877322880, 1829987584, 1779888768, 1727321472, 1672588416, 1615997056 +}; + +const Word32 lag_window_12k8_32[NUM_LAGW_STRENGTHS][16] = +{ + /* LAGW_WEAK */ + { + 2147165440, 2146854912, 2146337792, 2145613824, 2144683392, 2143546880, 2142204288, 2140656384, 2138903424, 2136945792, 2134784256, 2132419328, 2129851776, 2127082368, 2124111616, 2120940800 +}, +/* LAGW_MEDIUM */ +{ + 2146854912, 2145613824, 2143546880, 2140656384, 2136945792, 2132419328, 2127082368, 2120940800, 2114001792, 2106273280, 2097764224, 2088484096, 2078443648, 2067654016, 2056127616, 2043877504 +}, +/* LAGW_STRONG */ +{ + 2146337792, 2143546880, 2138903424, 2132419328, 2124111616, 2114001792, 2102115712, 2088484096, 2073141760, 2056127616, 2037485184, 2017261056, 1995505920, 1972273792, 1947621888, 1921610496 +} +}; + +const Word32 lag_window_16k_32[NUM_LAGW_STRENGTHS][16] = +{ + /* LAGW_WEAK */ + { + 2147202688, 2147003904, 2146673024, 2146209536, 2145613824, 2144886016, 2144026240, 2143034496, 2141911168, 2140656384, 2139270272, 2137753344, 2136105600, 2134327424, 2132419328, 2130381440 +}, +/* LAGW_MEDIUM */ +{ + 2147003904, 2146209536, 2144886016, 2143034496, 2140656384, 2137753344, 2134327424, 2130381440, 2125918208, 2120940800, 2115453056, 2109458944, 2102962816, 2095969536, 2088484096, 2080512000 +}, +/* LAGW_STRONG */ +{ + 2146673024, 2144886016, 2141911168, 2137753344, 2132419328, 2125918208, 2118260480, 2109458944, 2099527936, 2088484096, 2076345344, 2063131264, 2048863616, 2033565312, 2017261056, 1999976832 +} +}; +const Word32 lag_window_25k6_32[NUM_LAGW_STRENGTHS][16] = +{ + /* LAGW_WEAK */ + { + 2147243008, 2147165440, 2147036032, 2146854912, 2146622336, 2146337792, 2146001664, 2145613824, 2145174400, 2144683392, 2144140928, 2143546880, 2142901376, 2142204288, 2141456000, 2140656384 +}, +/* LAGW_MEDIUM */ +{ + 2147165440, 2146854912, 2146337792, 2145613824, 2144683392, 2143546880, 2142204288, 2140656384, 2138903424, 2136945792, 2134784256, 2132419328, 2129851776, 2127082368, 2124111616, 2120940800 +}, +/* LAGW_STRONG */ +{ + 2147036032, 2146337792, 2145174400, 2143546880, 2141456000, 2138903424, 2135890432, 2132419328, 2128492288, 2124111616, 2119280512, 2114001792, 2108279040, 2102115712, 2095516032, 2088484096 +} +}; +const Word32 lag_window_32k_32[NUM_LAGW_STRENGTHS][16] = +{ + /* LAGW_WEAK */ + { + 2147252352, 2147202688, 2147119872, 2147003904, 2146854912, 2146673024, 2146457728, 2146209536, 2145928192, 2145613824, 2145266432, 2144886016, 2144472576, 2144026240, 2143546880, 2143034496 +}, +/* LAGW_MEDIUM */ +{ + 2147202688, 2147003904, 2146673024, 2146209536, 2145613824, 2144886016, 2144026240, 2143034496, 2141911168, 2140656384, 2139270272, 2137753344, 2136105600, 2134327424, 2132419328, 2130381440 +}, +/* LAGW_STRONG */ +{ + 2147119872, 2146673024, 2145928192, 2144886016, 2143546880, 2141911168, 2139979776, 2137753344, 2135232896, 2132419328, 2129314048, 2125918208, 2122233088, 2118260480, 2114001792, 2109458944 +} +}; +const Word32 lag_window_48k_32[16] = /* LAGW_STRONG */ +{ + 2147202688, 2147003904, 2146673024, 2146209536, 2145613824, 2144886016, 2144026240, 2143034496, 2141911168, 2140656384, 2139270272, 2137753344, 2136105600, 2134327424, 2132419328, 2130381440 +}; /*----------------------------------------------------------------------------------* * LP analysis - grid of points for evaluating Chebyshev polynomials *----------------------------------------------------------------------------------*/ diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index e662b8a9996e1091e36a30896042e5bd111f51a3..3bbdeb87eb5d2950ee0f9fb93fd0dd7931d387e7 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -229,6 +229,13 @@ extern const Word16 lag_window_16k[NUM_LAGW_STRENGTHS][2][16]; extern const Word16 lag_window_25k6[NUM_LAGW_STRENGTHS][2][16]; extern const Word16 lag_window_32k[NUM_LAGW_STRENGTHS][2][16]; extern const Word16 lag_window_48k[2][16]; + +extern const Word32 lag_window_8k_32[16]; +extern const Word32 lag_window_12k8_32[NUM_LAGW_STRENGTHS][16]; +extern const Word32 lag_window_16k_32[NUM_LAGW_STRENGTHS][16]; +extern const Word32 lag_window_25k6_32[NUM_LAGW_STRENGTHS][16]; +extern const Word32 lag_window_32k_32[NUM_LAGW_STRENGTHS][16]; +extern const Word32 lag_window_48k_32[16]; extern const float interpol_frac2[]; /* LPC interpolation coefficients for two-subframe mode */ extern const float interpol_frac2_mid[]; /* LPC interpolation coefficients with mid-ISFs for two-subframe mode */ extern const float interpol_frac_12k8[]; /* LPC interpolation coefficients */ diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 200bf1a788edbcce6d57a0a6db162cedd0a33654..a534f1341628175bfa8ba2ef5e61c57ca461b56f 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -1166,7 +1166,7 @@ static void ITF_TnsFilter_fx( L_tmp = L_add(p[0], 0); FOR (i = 1; i < order; i++) { - L_tmp = L_add(L_tmp, L_shl(Mpy_32_16_1(p[-i], A[i]), shift)); + L_tmp = L_add_sat(L_tmp, L_shl(Mpy_32_16_1(p[-i], A[i]), shift)); } output[j] = L_tmp; move32(); diff --git a/lib_com/tools.c b/lib_com/tools.c index 57e4afdb78a13f34e52c8560147aa3b35302b016..815cc2a75e54ccb1975a7ba675d599772c950566 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -1278,6 +1278,23 @@ void v_multc_fixed_16( return; } +void v_multc_fixed_16_16( + const Word16 x[], /* i : Input vector */ + const Word16 c, /* i : Constant */ + Word16 y[], /* o : Output vector that contains c*x */ + const Word16 N /* i : Vector length */ +) +{ + Word16 i; + + FOR ( i = 0; i < N; i++ ) + { + y[i] = mult_r( x[i], c ); + } + + return; +} + /*-------------------------------------------------------------------* * squant() * diff --git a/lib_com/window_fx.c b/lib_com/window_fx.c index 4df9da9cde383482d2f10a47207f5a94451d5b35..a32033be12cf660d5607398d71857649e6bcf016 100644 --- a/lib_com/window_fx.c +++ b/lib_com/window_fx.c @@ -79,3 +79,34 @@ void ham_cos_window( return; } +void ham_cos_window_ivas( + Word16 *fh, /* o: 0Q15 */ + const Word16 n1, /* i: */ + const Word16 n2 /* i: */ +) +{ + Word16 cc_fx, cte_fx; + Word16 i; + + // cte = PI2 / (float) ( 2 * n1 - 1 ); + cte_fx = div_s(1, sub(shl(n1, 1), 1)); + cc_fx = 0; + move16(); + for ( i = 0; i < n1; i++ ) + { + *fh++ = sub(17694, mult(getCosWord16R2( cc_fx ), 15073)); + cc_fx = div_s(add(i, 1), sub(shl(n1, 1), 1));//add(cc_fx, cte_fx); + } + + // cte = PI2 / (float) ( 4 * n2 - 1 ); + cte_fx = div_s(1, sub(shl(n2, 2), 1)); + cc_fx = 0; + move16(); + for ( i = 0; i < n2; i++ ) + { + *fh++ = getCosWord16R2( cc_fx ); + cc_fx = div_s(add(i, 1), sub(shl(n1, 2), 1));; + } + + return; +} diff --git a/lib_com/window_ola_fx.c b/lib_com/window_ola_fx.c index 4726fc81ef21817827737de05e76056ff2d45b83..38cc8afaf6a7a80e530722cd2896460175050ddc 100644 --- a/lib_com/window_ola_fx.c +++ b/lib_com/window_ola_fx.c @@ -463,7 +463,7 @@ void window_ola_fx( } FOR (i =0; i < n; i++) { - *p1++=round_fx(L_sub(L_deposit_h(*p4++),L_shl(*pa--,1))); + *p1++=round_fx(L_sub_sat(L_deposit_h(*p4++),L_shl(*pa--,1))); /* paout[L/2 + i] = -ImdctOut[L - 1 - i] + OldauOut[i+L/2]; */ } } diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index f4684f7a6966a3d53cbbaac33bb3bc843af56e86..1bb7d96256a87160d0e7e5e0ae9e3d6b9720c47c 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -281,7 +281,6 @@ void decoder_tcx_post_flt( * * *-------------------------------------------------------------------*/ - void IMDCT_flt( float *x, float *old_syn_overl, @@ -591,18 +590,40 @@ void IMDCT_flt( if ( st->element_mode == IVAS_CPE_MDCT && ( st->last_core_brate <= SID_2k40 || st->last_core == ACELP_CORE ) && !fullbandScale ) { float buf[L_FRAME_MAX / 4]; - float window_buf[L_FRAME_MAX / 4]; - float r[M + 1]; const int16_t analysis_len = L_frame_glob / 4; /* get the first 5 ms of non-aliased TCX syntesis */ mvr2r( xn_buf + overlap / 2 + 2 * acelp_mem_len, &buf[0], analysis_len ); /* get LPC from that signal part to use for acelp zir smoothing */ +#ifdef IVAS_FLOAT_FIXED + Word16 buf_fx[L_FRAME_MAX / 4]; + Word16 window_buf_fx[L_FRAME_MAX / 4]; + Word32 r_fx[M + 1]; + Word16 q_r, q_old_Aq_12_8, q_buf; + f2me_buf_16(buf, buf_fx, &q_buf, analysis_len); + q_buf = sub(15, q_buf); + q_old_Aq_12_8 = 28; + Word32 old_Aq_12_8_fx[17]; + FOR(Word16 ind = 0; ind < 17; ind++) { + old_Aq_12_8_fx[ind] = float_to_fix(st->old_Aq_12_8[ind], q_old_Aq_12_8); + } + ham_cos_window_ivas( &window_buf_fx[0], analysis_len / 2, analysis_len / 2 ); + autocorr_fx_32( &buf_fx[0], M, &r_fx[0], &q_r, analysis_len, &window_buf_fx[0], 0, 0 ); + lag_wind_32( r_fx, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG ); + lev_dur_fx( &old_Aq_12_8_fx[0], &r_fx[0], M, NULL, q_old_Aq_12_8, q_buf * 2 + q_r + 1 ); + FOR(Word16 ind = 0; ind < 17; ind++) { + st->old_Aq_12_8[ind] = fix_to_float(old_Aq_12_8_fx[ind], q_old_Aq_12_8); + } +#else + + float window_buf[L_FRAME_MAX / 4]; + float r[M + 1]; ham_cos_window_flt( &window_buf[0], analysis_len / 2, analysis_len / 2 ); autocorr( &buf[0], &r[0], M, analysis_len, &window_buf[0], 0, 0, 0 ); lag_wind_flt( r, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG ); lev_dur( &st->old_Aq_12_8[0], &r[0], M, NULL ); +#endif } /* Window current frame */ @@ -735,7 +756,6 @@ void IMDCT_flt( return; } - /*-------------------------------------------------------------------* * decoder_tcx_invQ * @@ -1876,7 +1896,6 @@ void decoder_tcx_imdct( if ( st->element_mode != IVAS_CPE_DFT && !sba_dirac_stereo_flag ) { - IMDCT_flt( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_outLB, 0, st, 0, acelp_zir ); @@ -1917,21 +1936,19 @@ void decoder_tcx_imdct( { mvr2r( x, xn_bufFB, max( L_spec, max( L_frame, L_frameTCX ) ) ); - + IMDCT_flt( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_outLB, 0, st, 0, acelp_zir ); } if ( st->element_mode != EVS_MONO ) { - IMDCT_flt( x_tmp, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); } else { - IMDCT_flt( x, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); } @@ -1977,71 +1994,42 @@ void decoder_tcx_imdct( #ifdef IVAS_FLOAT_FIXED void decoder_tcx_imdct_fx( Decoder_State *st, /* i/o: coder memory state */ - const int16_t L_frame_glob, /* i : frame length */ - const int16_t L_frameTCX_glob, - const int16_t L_spec, - const int16_t tcx_offset, - const int16_t tcx_offsetFB, - const int16_t L_frame, - const int16_t L_frameTCX, - const int16_t left_rect, - float x[N_MAX], - float xn_buf[], - const uint16_t kernelType, /* i : TCX transform kernel type */ - const int16_t fUseTns, /* i : flag that is set if TNS data is present */ - float synth[], /* i/o: synth[-M..L_frame] */ - float synthFB[], - const int16_t bfi, /* i : Bad frame indicator */ - const int16_t frame_cnt, /* i : frame counter in the super frame */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_frameTCX_glob, + const Word16 L_spec, + const Word16 tcx_offset, + const Word16 tcx_offsetFB, + const Word16 L_frame, + const Word16 L_frameTCX, + const Word16 left_rect, + Word32 x_fx[N_MAX], //Q(11) + Word16 q_x, + Word16 xn_buf_fx[], //Q(-2) + Word16 q_win, + const UWord16 kernelType, /* i : TCX transform kernel type */ + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + Word16 synth_fx[], //Q(-2) /* i/o: synth[-M..L_frame] */ + Word16 synthFB_fx[], //Q(-2) + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ) { - int16_t j, L, overlap, curr_order, startLine, endLine, isTCX5; - int16_t overlapFB; - float x_tmp[L_FRAME_PLUS]; + Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; + Word16 overlapFB; Word32 x_tmp_fx[L_FRAME_PLUS]; - float xn_bufFB[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; - Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; - float acelp_zir[L_FRAME_MAX / 2]; + Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; + Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 acelp_zir_fx[L_FRAME_MAX / 2]; Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; - float A_itf[ITF_MAX_FILTER_ORDER + 1]; - float predictionGain; - int16_t index, proc = 0; + Word16 index, proc = 0; TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; TCX_DEC_HANDLE hTcxDec = st->hTcxDec; TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - // - - Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1], q_a_itf = 15; - Word32 x_fx[1200]; - Word16 x_e, predictionGain_fx = 0; - - /*x_e = 31; - IF(st->igf) FOR(Word16 i = 0; i < 1200; i++) if(abs((Word32) x[i])!=0) { - x_e = min(x_e, norm_l((Word32)x[i])); - } - IF(st->igf) FOR(Word16 i = 0; i < 1200; i++) { - x_fx[i] = (Word32)(x[i] * (1 << x_e)); - } - x_e = 31 - x_e;*/ - f2me_buf(x, x_fx, &x_e, s_min(s_max(s_max(L_frame, L_frameTCX), L_spec), 1200) ); - st->hIGFDec->virtualSpec_e = 31; - IF ( NE_16(st->igf, 0) ) - FOR(Word16 i = 0; i < s_min(st->hIGFDec->infoIGFStopLine - st->hIGFDec->infoIGFStartLine, 856); i++) if(abs((Word32) st->hIGFDec->virtualSpec_float[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i])!=0) { - st->hIGFDec->virtualSpec_e = s_min(st->hIGFDec->virtualSpec_e, norm_l((Word32)st->hIGFDec->virtualSpec_float[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i])); - } - IF ( NE_16(st->igf, 0) ) - FOR(Word16 i = 0; i < s_min(st->hIGFDec->infoIGFStopLine - st->hIGFDec->infoIGFStartLine, 856); i++) { - st->hIGFDec->virtualSpec_fx[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i] = (Word32)(st->hIGFDec->virtualSpec_float[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i] * (1 << st->hIGFDec->virtualSpec_e)); - } - st->hIGFDec->virtualSpec_e = 31 - st->hIGFDec->virtualSpec_e; - IF(st->hIGFDec->virtualSpec_e > x_e) { - FOR(Word16 i = 0; i < s_min(s_max(s_max(L_frame, L_frameTCX), L_spec), 1200); i++) x_fx[i] = L_shr(x_fx[i], st->hIGFDec->virtualSpec_e - x_e); - x_e = st->hIGFDec->virtualSpec_e; - } - // - -#ifdef IVAS_FLOAT_FIXED + Word16 predictionGain_fx; + Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; + Word16 q_a_itf = 15; + Word16 x_e = 31 - q_x; /*-----------------------------------------------------------------* * Initializations @@ -2116,33 +2104,21 @@ void decoder_tcx_imdct_fx( { x_itf_fx[j - IGF_START_MN] = x_fx[j]; move32(); - x_fx[j] = L_shr(st->hIGFDec->virtualSpec_fx[j - IGF_START_MN], sub(x_e, st->hIGFDec->virtualSpec_e)); + x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; + move32(); } } ITF_Detect_ivas_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order,shl(x_e, 1) ); - Word16 s = getScaleFactor32(x_fx, s_max(endLine, shr(L, 1))); - s = sub(s, 2); - IF(s <= 0) - { - FOR(j = 0; j < s_max(endLine, shr(L, 1)); j++) - { - x_fx[j] = L_shl(x_fx[j], s); - move32(); - } - x_e = sub(x_e, s); - } ELSE { - s = 0; - } - ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); FOR ( j = startLine; j < endLine; j++ ) { IF ( st->hIGFDec->flag_sparse[j - IGF_START_MN] == 2 ) { - x_fx[j] = L_shl(x_itf_fx[j - IGF_START_MN], s); + x_fx[j] = x_itf_fx[j - IGF_START_MN]; + move32(); } } @@ -2181,214 +2157,98 @@ void decoder_tcx_imdct_fx( set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); } - - fixedToFloat_arr(A_itf_fx, A_itf, 15, 17); - IF(st->igf && proc) me2f_buf(x_fx, x_e, x, s_max(st->hIGFDec->infoIGFStopLine, s_max(L_frameTCX, L_spec) ) ); - me2f_buf(x_tmp_fx, x_e, x_tmp, L_FRAME_PLUS ); - me2f_buf(xn_bufFB_fx, x_e, xn_bufFB, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ); - predictionGain = fix16_to_float(predictionGain_fx, 15); -#else - float x_itf[N_MAX_TCX - IGF_START_MN]; - /*-----------------------------------------------------------------* - * Initializations - *-----------------------------------------------------------------*/ - - /* Init lengths */ - overlap = hTcxCfg->tcx_mdct_window_length; - overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && frame_cnt && !bfi && st->last_core != ACELP_CORE ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - } - - if ( st->igf ) - { - proc = st->hIGFDec->flatteningTrigger; - - if ( proc && fUseTns != 0 ) - { - proc = 0; - } - - if ( proc ) - { - startLine = st->hIGFDec->infoIGFStartLine; - endLine = st->hIGFDec->infoIGFStopLine; - curr_order = 0; - predictionGain = 0; - L = L_frameTCX; - isTCX5 = 0; - - /* interleave again for ITF */ - if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly ) - { - if ( ( hTcxCfg->fIsTNSAllowed && fUseTns != 0 && bfi != 1 ) || ( L_spec > L_frameTCX ) ) - { - L = L_spec; - } - - if ( ( ( !bfi ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || - ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || - ( ( bfi ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && - !( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - - tcx5SpectrumInterleaving( L >> 1, x ); - } - } - - for ( j = startLine; j < endLine; j++ ) - { - if ( st->hIGFDec->flag_sparse[j - IGF_START_MN] == 2 ) - { - x_itf[j - IGF_START_MN] = x[j]; - x[j] = st->hIGFDec->virtualSpec_float[j - IGF_START_MN]; - } - } - - ITF_Detect( x + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf, &predictionGain, &curr_order ); - - ITF_Apply( x, startLine, endLine, A_itf, curr_order ); - - for ( j = startLine; j < endLine; j++ ) - { - if ( st->hIGFDec->flag_sparse[j - IGF_START_MN] == 2 ) - { - x[j] = x_itf[j - IGF_START_MN]; - } - } - - /* deinterleave */ - if ( isTCX5 ) - { - tcx5SpectrumDeinterleaving( L >> 1, x ); - } - } - } - - /*-----------------------------------------------------------* - * Prepare OLA buffer after waveadjustment. * - * Compute inverse MDCT of x[]. * - *-----------------------------------------------------------*/ - - - if ( st->element_mode == IVAS_CPE_MDCT ) - { - set_f( x_tmp, 0.0f, L_FRAME_PLUS ); - mvr2r( x, x_tmp, min( L_FRAME48k, max( L_spec, max( L_frame, L_frameTCX ) ) ) ); - mvr2r( x, xn_bufFB, min( L_FRAME48k, max( L_spec, max( L_frame, L_frameTCX ) ) ) ); - } - else if ( st->element_mode == EVS_MONO ) + IF ( st->element_mode != IVAS_CPE_DFT && !sba_dirac_stereo_flag ) { - mvr2r( x, xn_bufFB, max( L_spec, max( L_frame, L_frameTCX ) ) ); - } - else - { - mvr2r( x, x_tmp, max( L_spec, max( L_frame, L_frameTCX ) ) ); - mvr2r( x, xn_bufFB, max( L_spec, max( L_frame, L_frameTCX ) ) ); - } - if ( st->igf ) - { - set_zero( xn_bufFB + st->hIGFDec->infoIGFStartLine, L_frameTCX - st->hIGFDec->infoIGFStartLine ); - } -#endif - if ( st->element_mode != IVAS_CPE_DFT && !sba_dirac_stereo_flag ) - { - - IMDCT_flt( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, - hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_outLB, 0, st, 0, acelp_zir ); + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, + hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr(s_max( L_frameTCX, L_spec ), 1), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx ); } /* Generate additional comfort noise to mask potential coding artefacts */ - if ( st->flag_cna && st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && !st->cna_dirac_flag ) + IF ( NE_16(st->flag_cna, 0) && NE_16(st->element_mode, IVAS_CPE_TD) && NE_16(st->element_mode, IVAS_CPE_DFT) && EQ_16(st->cna_dirac_flag, 0) ) { -#ifdef IVAS_FLOAT_FIXED - float maxim = 0; - f2me_buf(x, x_fx, &x_e, L_frame); - maxim = 0; - FOR(Word16 ind = 0; ind < FFTCLDFBLEN; ind++) - { - maxim = fmaxf(maxim, fabsf(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[ind])); - } - st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31; - IF(L_abs((Word32)maxim)!=0) st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = norm_l((Word32)maxim); - FOR(Word16 ind = 0; ind < FFTCLDFBLEN; ind++) - { - st->hFdCngDec->hFdCngCom->cngNoiseLevel[ind] = (Word32)(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[ind] * (1LL<hFdCngDec->hFdCngCom->q_cngNoiseLevel)); - } - st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = float_to_fix16(st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt, 15); - generate_masking_noise_mdct( x_fx, &x_e, st->hFdCngDec->hFdCngCom, L_frame ); - - me2f_buf(x_fx, x_e, x, L_frame); -#else - generate_masking_noise_mdct_flt( x, st->hFdCngDec->hFdCngCom ); -#endif + FOR(Word16 ind = 0; ind < L_frame; ind++) { + x_fx[ind] = L_shr(x_fx[ind], sub(31, add(x_e, q_x))); + } } - if ( st->element_mode == IVAS_CPE_DFT || sba_dirac_stereo_flag ) + IF ( EQ_16(st->element_mode, IVAS_CPE_DFT) || NE_16(sba_dirac_stereo_flag, 0) ) { - mvr2r( x, xn_bufFB, max( L_spec, max( L_frame, L_frameTCX ) ) ); - + mvl2l( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); - IMDCT_flt( xn_bufFB, hTcxDec->syn_Overl_float, hTcxDec->syn_Overl_TDAC_float, xn_buf, hTcxCfg->tcx_aldo_window_1_trunc_flt, hTcxCfg->tcx_aldo_window_2_flt, hTcxCfg->tcx_mdct_window_half_flt, hTcxCfg->tcx_mdct_window_minimum_flt, hTcxCfg->tcx_mdct_window_trans_flt, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_outLB, 0, st, 0, acelp_zir ); + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr(s_max( L_frameTCX, L_spec ), 1), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx ); } - if ( st->element_mode != EVS_MONO ) + IF ( NE_16(st->element_mode, EVS_MONO) ) { - - IMDCT_flt( x_tmp, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, - hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); + FOR(Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++) { + xn_bufFB_fx_16[ind] = (Word16)L_shr(xn_bufFB_fx[ind], (q_x - q_win)); + } + IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, + hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir_fx ); + FOR(Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++) { + xn_bufFB_fx[ind] = L_shl(xn_bufFB_fx_16[ind], (q_x - q_win)); + } } - else + ELSE { - IMDCT_flt( x, hTcxDec->syn_OverlFB_float, hTcxDec->syn_Overl_TDACFB_float, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB_trunc_flt, hTcxCfg->tcx_aldo_window_2_FB_flt, hTcxCfg->tcx_mdct_window_halfFB_flt, hTcxCfg->tcx_mdct_window_minimumFB_flt, hTcxCfg->tcx_mdct_window_transFB_flt, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, max( L_frameTCX, L_spec ) >> 1, L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir ); + IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_buf_fx, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, FSCALE_DENOM * L_frameTCX_glob / L_frame_glob, acelp_zir_fx ); } - /* PLC: [TCX: Tonal Concealment] */ - if ( !bfi ) + IF ( EQ_16(bfi, 0) ) { + Word16 res_m, res_e = 0; st->second_last_tns_active = st->last_tns_active; + move16(); st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; - hTcxDec->tcxltp_third_last_pitch_float = hTcxDec->tcxltp_second_last_pitch_float; - hTcxDec->tcxltp_second_last_pitch_float = st->old_fpitch_float; - st->old_fpitch_float = hTcxLtpDec->tcxltp_pitch_int + hTcxLtpDec->tcxltp_pitch_fr / (float) st->pit_res_max; + move16(); + hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; + move32(); + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + move32(); + res_m = BASOP_Util_Divide1616_Scale(hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e); + st->old_fpitch = L_add(L_shl(hTcxLtpDec->tcxltp_pitch_int, 16), L_shl(res_m, add(res_e, 1))); - if ( st->element_mode == IVAS_CPE_MDCT ) + IF ( EQ_16(st->element_mode, IVAS_CPE_MDCT) ) { - st->old_fpitch_float *= (float) L_frame_glob / (float) L_FRAME; + res_m = BASOP_Util_Divide1616_Scale(L_frame_glob, L_FRAME, &res_e); + st->old_fpitch = L_shl(Mpy_32_16_1(st->old_fpitch, res_m), res_e); } - if ( st->element_mode > EVS_MONO ) + IF ( GT_16(st->element_mode, EVS_MONO) ) { - st->old_fpitchFB_float = st->old_fpitch_float * (float) L_frameTCX_glob / (float) L_frame_glob; + res_m = BASOP_Util_Divide1616_Scale(L_frameTCX_glob, L_frame_glob, &res_e); + st->old_fpitchFB = L_shl(Mpy_32_16_1(st->old_fpitch, res_m), res_e); } - else + ELSE { - st->old_fpitchFB_float = st->old_fpitch_float * (float) L_frameTCX / (float) L_frame; + res_m = BASOP_Util_Divide1616_Scale(L_frameTCX, L_frame, &res_e); + st->old_fpitchFB = L_shl(Mpy_32_16_1(st->old_fpitch, res_m), res_e); } } /* Update old_syn_overl */ - if ( !hTcxCfg->last_aldo ) + IF ( EQ_16(hTcxCfg->last_aldo, 0) ) { - mvr2r( xn_buf + L_frame, hTcxDec->syn_Overl_float, overlap ); - mvr2r( xn_bufFB + L_frameTCX, hTcxDec->syn_OverlFB_float, overlapFB ); + mvs2s( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); + FOR(Word16 ind = 0; ind < overlapFB; ind++) { + hTcxDec->syn_OverlFB[ind] = (Word16)L_shr(xn_bufFB_fx[ add(ind, L_frameTCX) ], sub(q_x, q_win)); + } } /* Output */ - mvr2r( xn_buf + ( overlap >> 1 ) - tcx_offset, synth, L_frame_glob ); - mvr2r( xn_bufFB + ( overlapFB >> 1 ) - tcx_offsetFB, synthFB, L_frameTCX_glob ); + mvs2s( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset), synth_fx, L_frame_glob ); + FOR(Word16 ind = 0; ind < L_frameTCX_glob; ind++) { + synthFB_fx[ind] = (Word16)L_shr(xn_bufFB_fx[ add( ind, sub( shr( overlapFB, 1 ), tcx_offsetFB)) ], sub(q_x, q_win)); + } + + return; } diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index a20e8ca65aada835d205f8ccdc9781b07b29651e..39c2f98bbf871a799182397da288a93d31b90a2a 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -2359,6 +2359,491 @@ void IMDCT(Word32 *x, Word16 x_e, } } +#ifdef IVAS_FLOAT_FIXED +void IMDCT_ivas_fx( + Word32 *x_fx, //Q(q_x) + Word16 q_x, + Word16 *old_syn_overl_fx, //Q(-2) + Word16 *syn_Overl_TDAC_fx, //Q(-2) + Word16 *xn_buf_fx, //Q(-2) + const Word16 *tcx_aldo_window_1_fx, //Q(15) + const PWord16 *tcx_aldo_window_1_trunc_fx, //Q(15) + const PWord16 *tcx_aldo_window_2_fx, //Q(15) + const PWord16 *tcx_mdct_window_half_fx, //Q(15) + const PWord16 *tcx_mdct_window_minimum_fx, //Q(15) + const PWord16 *tcx_mdct_window_trans_fx, //Q(15) + const Word16 tcx_mdct_window_half_length, //Q(15) + const Word16 tcx_mdct_window_min_length, //Q(15) + Word16 index, + const UWord16 kernel_type, /* i : TCX transform kernel type */ + const Word16 left_rect, + const Word16 tcx_offset, + const Word16 overlap, + const Word16 L_frame, + const Word16 L_frameTCX, + const Word16 L_spec_TCX5, + const Word16 L_frame_glob, + const Word16 frame_cnt, + const Word16 bfi, + Word16 *old_out_fx, //Q(-2) + const Word16 FB_flag, + Decoder_State *st, + const Word16 fullbandScale, + Word16 *acelp_zir_fx) //Q(-2) +{ + int16_t i, nz, aldo, w, L_win, L_ola; + Word16 win_fx[(L_FRAME_PLUS + L_MDCT_OVLP_MAX) / 2]; + TCX_DEC_HANDLE hTcxDec = st->hTcxDec; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + Word16 q_win, x_e_hdrm; + x_e_hdrm = 3; + q_win = q_x + x_e_hdrm - 16; + + aldo = 0; + + nz = NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) * L_frame / L_frameTCX; + + IF ( NE_16(st->element_mode, EVS_MONO) && EQ_16(frame_cnt, 0) && EQ_16(bfi, 0) && NE_16(st->prev_bfi, 0) && ( EQ_16(st->last_core_bfi, TCX_20_CORE) || EQ_16(st->last_core_bfi, TCX_10_CORE) ) && EQ_16(hTcxCfg->last_aldo, 0) ) + { + Word16 fac = shl(mult_r(hTcxDec->conceal_eof_gain, st->last_concealed_gain_syn_deemph), 1); + FOR(Word16 ind = 0; ind < overlap; ind++) { + old_syn_overl_fx[ind] = mult_r(old_syn_overl_fx[ind], fac); + } + } + + IF ( EQ_16( L_frameTCX, shr(hTcxDec->L_frameTCX, 1) ) && st->tcxonly ) + { + /* Mode decision in PLC + + last OL curr OL left TCX-10 right TCX-10 + ------------------------------------------------------------- + 0 0 2x TCX-5* 1x TCX-10 + 0 2 1x TCX-10 1x TCX-10 + 0 3 1x TCX-10 1x TCX-10 + 2 0 2x TCX-5 1x TCX-10 + 2 2 2x TCX-5 2x TCX-5 + 2 3 2x TCX-5 2x TCX-5 + 3 0 2x TCX-5 1x TCX-10 + 3 2 2x TCX-5 2x TCX-5 + 3 3 2x TCX-5 2x TCX-5 + */ + + IF( ( EQ_16(bfi, 0) && NE_16(hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP) ) || ( NE_16(bfi, 0) && NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) + { + /* minimum or half overlap, two transforms, grouping into one window */ + L_win = shr( L_frame, 1 ); + L_ola = EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ? tcx_mdct_window_min_length : tcx_mdct_window_half_length; + move16(); + + set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) ); + set16_fx( xn_buf_fx, 0, tcx_offset + ( L_ola >> 1 ) ); /* zero left end of buffer */ + + FOR( w = 0; w < 2; w++ ) + { + IF( EQ_16(kernel_type, MDST_IV) || s_and( kernel_type, w ) ) + { + TCX_MDST_Inverse_fx( x_fx + w * L_spec_TCX5, x_e_hdrm, win_fx, L_ola, L_win - L_ola, L_ola ); + } + ELSE IF( NE_16(kernel_type, 0) && EQ_16(w, 0) ) /* type 1 or 2 */ + { + TCX_MDXT_Inverse_fx( x_fx + w * L_spec_TCX5, x_e_hdrm, win_fx, L_ola, L_win - L_ola, L_ola, kernel_type ); + } + ELSE + { + TCX_MDCT_Inverse( x_fx + w * L_spec_TCX5, x_e_hdrm, win_fx, L_ola, L_win - L_ola, L_ola, st->element_mode ); + } + + tcx_windowing_synthesis_current_frame( win_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : (Word8) st->last_is_cng, fullbandScale ); + + IF( GT_16(w, 0) ) + { + tcx_windowing_synthesis_past_frame( xn_buf_fx + tcx_offset - shr( L_ola, 1 ) + w * L_win, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, MIN_OVERLAP ); + } + + /* add part of current sub-window overlapping with previous window */ + v_add_16( win_fx, xn_buf_fx + add(sub(tcx_offset, shr( L_ola, 1 )), i_mult(w, L_win)), xn_buf_fx + add(sub(tcx_offset, shr( L_ola, 1 )), i_mult(w, L_win)), L_ola ); + + /* copy new sub-window region not overlapping with previous window */ + mvs2s( win_fx + L_ola, xn_buf_fx + add(tcx_offset, add(shr( L_ola, 1 ), i_mult(w, L_win))), L_win ); + } + + /* To assure that no garbage values are passed to overlap */ + set16_fx( xn_buf_fx + add(L_frame, add(tcx_offset, shr( L_ola, 1 ))), 0, sub(overlap, add(tcx_offset, shr( L_ola, 1 ))) ); + + IF( NE_16(st->prev_bfi, 0) && EQ_16(frame_cnt, 0) && NE_16(st->last_core, st->last_core_bfi) && EQ_16(st->last_core_bfi, ACELP_CORE) ) + { + tcx_windowing_synthesis_past_frame( old_syn_overl_fx, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode ); + v_add_16( xn_buf_fx, old_syn_overl_fx, xn_buf_fx, overlap ); + } + } + ELSE IF ( EQ_16(bfi, 0) && EQ_16( frame_cnt, 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) + { + /* special overlap attempt, two transforms, grouping into one window */ + L_win = shr(L_frame, 1); + L_ola = tcx_mdct_window_min_length; + move16(); + + set16_fx( win_fx, 0, shr(add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1) ); + + /* 1st TCX-5 window, special MDCT with minimum overlap on right side */ + IF ( EQ_16(kernel_type, MDST_IV) ) + { + TCX_MDST_Inverse_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub(L_win, shr( L_ola, 1 )), L_ola ); + } + ELSE IF ( NE_16(kernel_type, MDCT_IV) ) /* type 1 or 2 */ + { + TCX_MDXT_Inverse_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub(L_win, shr( L_ola, 1 )), L_ola, kernel_type ); + } + ELSE + { + TCX_MDCT_Inverse( x_fx, x_e_hdrm, win_fx + L_win, 0, sub(L_win, shr( L_ola, 1 )), L_ola, st->element_mode ); + } + + set16_fx( xn_buf_fx, 0, shr( overlap, 1 ) ); + + /* copy new sub-window region not overlapping with previous window */ + mvs2s( win_fx + L_win, xn_buf_fx + shr( overlap, 1 ), add(L_win, shr( L_ola, 1 )) ); + + /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */ + IF ( s_and(kernel_type, 1) ) + { + TCX_MDST_Inverse_fx( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub(L_win, L_ola), L_ola ); + } + ELSE + { + TCX_MDCT_Inverse( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub(L_win, L_ola), L_ola, st->element_mode ); + } + + tcx_windowing_synthesis_current_frame( win_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 0, + /* left_rect */ MIN_OVERLAP, /* left_mode */ acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, L_win, LT_16(tcx_offset, 0) ? -tcx_offset : 0, 1, /* st->last_mode_bfi */ 0, /* st->last_is_cng */ fullbandScale ); + + tcx_windowing_synthesis_past_frame( xn_buf_fx + shr( overlap, 1 ) + sub(L_win, shr( L_ola, 1 )), tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 2 ); + + /* add part of current sub-window overlapping with previous window */ + v_add_16( win_fx, xn_buf_fx + add(shr( overlap, 1 ), sub(L_win, shr( L_ola, 1 ))), xn_buf_fx + sub(add(shr( overlap, 1 ), L_win), shr( L_ola, 1 )), L_ola ); + + /* copy new sub-window region not overlapping with previous window */ + mvs2s( win_fx + L_ola, xn_buf_fx + add(add(shr( overlap, 1 ), L_win), shr( L_ola, 1 )), L_win ); + + /* extra folding-out on left side of win, for perfect reconstruction */ + IF ( GE_16(kernel_type, MDCT_II) ) + { + FOR ( w = shr( overlap, 1 ); w < overlap; w++ ) + { + xn_buf_fx[sub(sub(overlap, 1), w)] = xn_buf_fx[w]; + move16(); + } + } + ELSE + { + FOR ( w = shr( overlap, 1 ); w < overlap; w++ ) + { + xn_buf_fx[sub(sub(overlap, 1), w)] = negate(xn_buf_fx[w]); + move16(); + } + } + tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, 0, /* left_mode */ acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shl(L_win, 1), LT_16(tcx_offset, 0) ? -tcx_offset : 0, st->last_core_bfi, (Word8)st->last_is_cng, fullbandScale ); + } + ELSE + { + /* default, i.e. maximum overlap, single transform, no grouping */ + IF ( EQ_16(kernel_type, MDST_IV) ) + { + TCX_MDST_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub(L_frame, overlap), overlap ); + } + ELSE IF ( NE_16(kernel_type, MDCT_IV) ) /* type 1 or 2 */ + { + TCX_MDXT_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub(L_frame, overlap), overlap, kernel_type ); + } + ELSE + { + TCX_MDCT_Inverse( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub(L_frame, overlap), overlap, st->element_mode ); + } + + tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, !bfi && GT_16( frame_cnt, 0 ) && EQ_16( index, 0 ) && NE_16( st->last_core, ACELP_CORE ) ? MIN_OVERLAP : index, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shr(L_frame_glob, 1), LT_16(tcx_offset, 0) ? -tcx_offset : 0, GT_16( frame_cnt, 0 /*|| (st->last_con_tcx )*/ ) ? 1 : st->last_core_bfi, GT_16( frame_cnt, 0 ) ? 0 : (Word8)st->last_is_cng, fullbandScale ); + + } /* tcx_last_overlap_mode != FULL_OVERLAP */ + } + ELSE + { + /* frame is TCX-20 or not TCX-only */ + assert( EQ_16(frame_cnt, 0) ); + IF ( NE_16(hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP) ) + { + + Word16 q_tmp_fx_32 = 15, q_xn_buf_fx_32 = q_x; + Word32 xn_buf_fx_32[2000] = { 0 }, tmp_fx_32[1200], old_out_fx_32[1200]; + + IF ( NE_16(kernel_type, MDCT_IV) ) /* inverse transform */ + { + + IF ( EQ_16(kernel_type, MDST_IV) ) + { + edst_fx( x_fx, xn_buf_fx_32 + overlap / 2 + nz, L_frame, &q_xn_buf_fx_32 ); + } + ELSE /* type 1 or 2 */ + { + edxt_fx( x_fx, xn_buf_fx_32 + overlap / 2 + nz, L_frame, kernel_type, TRUE ); + } + + Word16 res_m, res_e = 0; + res_m = BASOP_Util_Divide1616_Scale(L_frame, NORM_MDCT_FACTOR, &res_e); + res_m = Sqrt16(res_m, &res_e); + + FOR(Word16 ind = 0; ind < L_frame; ind++) { + tmp_fx_32[ind] = L_shl(Mpy_32_16_1(xn_buf_fx_32[shr(overlap, 1) + nz + ind], res_m), res_e); + } + q_tmp_fx_32 = q_xn_buf_fx_32; + move16(); + + FOR ( Word16 ind = 0; ind < L_frame; ind++ ) + { + old_out_fx_32[ind] = L_shl(old_out_fx[ind], sub(q_tmp_fx_32, q_win) ); + } + + window_ola_ext_fx( tmp_fx_32, xn_buf_fx_32, old_out_fx_32, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, kernel_type ); + + FOR ( Word16 ind = 0; ind < L_frame; ind++ ) + { + old_out_fx[ind] = (Word16) L_shr( old_out_fx_32[ind], sub(q_tmp_fx_32, q_win) ); + xn_buf_fx[ind] = (Word16)L_shr(xn_buf_fx_32[ind], sub(q_tmp_fx_32, q_win) ); + } + } + ELSE + { + Word16 q_old_out = q_win; + move16(); + edct_fx( x_fx, xn_buf_fx_32 + overlap / 2 + nz, L_frame, &q_xn_buf_fx_32 ); + Word16 res_m, res_e = 0; + move16(); + res_m = BASOP_Util_Divide1616_Scale(L_frame, NORM_MDCT_FACTOR, &res_e); + res_m = Sqrt16(res_m, &res_e); + + FOR(Word16 ind = 0; ind < L_frame; ind++) { + tmp_fx_32[ind] = Mpy_32_16_1(xn_buf_fx_32[shr(overlap, 1) + nz + ind], res_m); + } + q_tmp_fx_32 = sub(q_xn_buf_fx_32, res_e); + //v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame ); + + FOR(Word16 ind = 0; ind < L_frame; ind++) { + xn_buf_fx[add( add(ind, shr(overlap, 1)), nz)] = (Word16)L_shr(xn_buf_fx_32[add( add(ind, shr(overlap, 1)), nz)], sub(q_xn_buf_fx_32, q_win)); + } + + window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, &q_old_out, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL ); + + FOR(Word16 ind = 0; ind < L_frame; ind++) { + old_out_fx[ind] = shr_sat(old_out_fx[ind], sub(q_old_out, q_win)); + xn_buf_fx[ind] = shr_sat(xn_buf_fx[ind], sub(q_tmp_fx_32, q_win)); + } + } + aldo = 1; + move16(); + } + ELSE + { + Word16 acelp_mem_len = tcx_offset < 0 ? -tcx_offset : 0; + move16(); + + IF ( EQ_16(kernel_type, MDST_IV) ) + { + TCX_MDST_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap ); + } + ELSE IF ( kernel_type != MDCT_IV ) /* type 1 or 2 */ + { + TCX_MDXT_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, kernel_type ); + } + ELSE + { + TCX_MDCT_Inverse( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, st->element_mode ); + } + + /*-----------------------------------------------------------* + * Windowing, overlap and add * + *-----------------------------------------------------------*/ + + IF ( EQ_16(st->element_mode, IVAS_CPE_MDCT) && (LE_32( st->last_core_brate, SID_2k40) || EQ_16(st->last_core, ACELP_CORE) ) && EQ_16(fullbandScale, 0) ) + { + /* get LPC from that signal part to use for acelp zir smoothing */ + const Word16 analysis_len = L_frame_glob / 4; + Word16 buf_fx[L_FRAME_MAX / 4]; + Word16 window_buf_fx[L_FRAME_MAX / 4]; + Word32 r_fx[M + 1]; + Word16 q_r, q_old_Aq_12_8, q_buf; + + /* get the first 5 ms of non-aliased TCX syntesis */ + mvs2s( xn_buf_fx + add(shr(overlap, 1), shl(acelp_mem_len, 1)), &buf_fx[0], analysis_len ); + + q_buf = q_win; + move16(); + q_old_Aq_12_8 = 28; + move16(); + + ham_cos_window_ivas( &window_buf_fx[0], analysis_len / 2, analysis_len / 2 ); + autocorr_fx_32( &buf_fx[0], M, &r_fx[0], &q_r, analysis_len, &window_buf_fx[0], 0, 0 ); + lag_wind_32( r_fx, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG ); + lev_dur_fx( &st->old_Aq_12_8_fx_32[0], &r_fx[0], M, NULL, 28/*Q(st->q_old_Aq_12_8_fx_32)*/, add( add( shl(q_buf, 1), q_r), 1) ); + FOR(Word16 ind = 0; ind <= M; ind++) { + st->old_Aq_12_8_fx[ind] = (Word16) L_shr(st->old_Aq_12_8_fx_32[ind], 16); + } + } + + /* Window current frame */ + tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, hTcxCfg->tcx_last_overlap_mode, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shr(L_frame_glob, 1), acelp_mem_len, st->last_core_bfi, (Word8)st->last_is_cng, fullbandScale ); + } + } /* TCX-20 and TCX-only */ + + IF ( NE_16( frame_cnt, 0 ) || GT_16( st->last_core_bfi, ACELP_CORE ) ) + { + IF ( ( EQ_16( L_frameTCX, shr(hTcxDec->L_frameTCX, 1 ) ) && NE_16( st->tcxonly, 0 ) ) || + EQ_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) + { + IF ( EQ_16(bfi, 0) && GT_16( frame_cnt, 0 ) && EQ_16( index, 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && NE_16( st->last_core, ACELP_CORE ) ) + { + index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */ + move16(); + } + + IF ( NE_16(hTcxCfg->last_aldo, 0) ) + { + FOR ( i = 0; i < sub(overlap, tcx_mdct_window_min_length); i++ ) + { + xn_buf_fx[add(i, sub(shr(overlap, 1), tcx_offset))] = add(xn_buf_fx[add(i, sub(shr(overlap, 1), tcx_offset))], old_out_fx[add(i, nz)]); + } + + /* fade truncated ALDO window */ + IF ( EQ_16(L_frameTCX, shr(hTcxDec->L_frameTCX, 1)) && EQ_16(st->element_mode, IVAS_CPE_MDCT) && EQ_16(frame_cnt, 0) && EQ_16(hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP) ) + { + // tested + FOR ( ; i < overlap; i++ ) /* perfectly reconstructing ALDO shortening */ + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], old_out_fx[add(i, nz)]); + } + FOR ( i = 0; i < shr(tcx_mdct_window_min_length, 1); i++ ) + { + xn_buf_fx[add(sub(add(i, shr(overlap, 1)), tcx_offset), overlap)] = add(xn_buf_fx[add(sub(add(i, shr(overlap, 1)), tcx_offset), overlap)], mult_r(old_out_fx[add(add(i, nz), overlap)], tcx_mdct_window_minimum_fx[i].v.re)); + } + FOR ( ; i < tcx_mdct_window_min_length; i++ ) + { + xn_buf_fx[add(sub(add(i, shr(overlap, 1)), tcx_offset), overlap)] = add(xn_buf_fx[add(sub(add(i, shr(overlap, 1)), tcx_offset), overlap)], mult_r(old_out_fx[add(add(i, nz), overlap)], tcx_mdct_window_minimum_fx[sub(tcx_mdct_window_min_length, add(1, i))].v.im)); + } + } + ELSE + { + FOR ( ; i < sub(overlap, shr(tcx_mdct_window_min_length, 1)); i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r(old_out_fx[add(i, nz)], tcx_mdct_window_minimum_fx[add(sub(tcx_mdct_window_min_length, overlap), i)].v.re)); + } + FOR ( ; i < overlap; i++ ) + { + xn_buf_fx[add(i, sub(shr(overlap, 1), tcx_offset))] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r(old_out_fx[add(i, nz)], tcx_mdct_window_minimum_fx[sub(overlap, add(1, i))].v.im)); + } + } + } + ELSE + { + tcx_windowing_synthesis_past_frame( old_syn_overl_fx, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( EQ_16(index, 0) || EQ_16(hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP) ) ? hTcxCfg->tcx_last_overlap_mode : index ); + + IF ( NE_16(bfi, 0) ) + { + FOR ( i = 0; i < shr(tcx_mdct_window_half_length, 1); i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r(old_syn_overl_fx[i], tcx_mdct_window_half_fx[i].v.re)); + } + FOR ( ; i < tcx_mdct_window_half_length; i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r(old_syn_overl_fx[i], tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.im)); + } + } + ELSE IF ( EQ_16(left_rect, 0) ) + { + FOR ( i = 0; i < overlap; i++ ) + { + xn_buf_fx[i] = add(xn_buf_fx[i], old_syn_overl_fx[i]); + } + } + ELSE + { + FOR ( i = 0; i < overlap; i++ ) + { + xn_buf_fx[i + shr( overlap, 1 )] = add(xn_buf_fx[i + shr( overlap, 1 )], old_syn_overl_fx[i]); + } + } + } + } + } + + IF ( EQ_16(aldo, 0) && ( ( EQ_16( L_frameTCX, shr(hTcxDec->L_frameTCX, 1) ) && GT_16(frame_cnt, 0) ) || NE_16(L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) ) + { + /* Compute windowed synthesis in case of switching to ALDO windows in next frame */ + mvs2s( xn_buf_fx + sub(L_frame, nz), old_out_fx, add(nz, overlap) ); + set16_fx( old_out_fx + add(nz, overlap), 0, nz ); + + tcx_windowing_synthesis_past_frame( old_out_fx + nz, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_curr_overlap_mode ); + + /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */ + IF ( EQ_16(hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP) ) + { + //tested + IF ( s_and(kernel_type, 1) ) + { + FOR ( i = 0; i < nz; i++ ) + { + old_out_fx[add(add(nz, overlap), i)] = negate( mult_r( xn_buf_fx[sub(L_frame, add(1, i))], tcx_aldo_window_1_fx[sub(nz, add(1, i))] ) ); + } + } + ELSE + { + FOR ( i = 0; i < nz; i++ ) + { + old_out_fx[add(add(nz, overlap), i)] = mult_r( xn_buf_fx[sub(L_frame, add(1, i))], tcx_aldo_window_1_fx[sub(nz, add(1, i))]); + } + } + aldo = 1; + move16(); + } + } + + IF ( NE_16(FB_flag , 0) ) + { + hTcxCfg->last_aldo = aldo; + move16(); + } + + /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */ + IF ( NE_16(left_rect, 0) && EQ_16( frame_cnt, 0 ) && EQ_16( st->last_core_bfi, ACELP_CORE ) && NE_16(st->prev_bfi, 0) ) + { + IF ( NE_16(FB_flag, 0) ) + { + FOR ( i = 0; i < shr(tcx_mdct_window_half_length, 1); i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = mult_r(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], tcx_mdct_window_half_fx[i].v.im); + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r( mult_r( hTcxDec->syn_OverlFB[i], tcx_mdct_window_half_fx[i].v.re), tcx_mdct_window_half_fx[i].v.re)); + } + FOR ( ; i < tcx_mdct_window_half_length; i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = mult_r(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.re ); + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r( mult_r( hTcxDec->syn_OverlFB[i], tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.im), tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.im)); + } + } + ELSE + { + FOR ( i = 0; i < shr(tcx_mdct_window_half_length, 1); i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = mult_r(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], tcx_mdct_window_half_fx[i].v.im); + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[i].v.re), tcx_mdct_window_half_fx[i].v.re)); + } + FOR ( ; i < tcx_mdct_window_half_length; i++ ) + { + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = mult_r(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.re); + xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)] = add(xn_buf_fx[sub(add(i, shr(overlap, 1)), tcx_offset)], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.im), tcx_mdct_window_half_fx[sub(tcx_mdct_window_half_length, add(1, i))].v.im)); + } + } + } + + return; +} +#endif + void init_tcx_info_fx( Decoder_State *st, /* i/o: coder memory state */ const Word16 L_frame_glob, /* i : global frame length */ diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index c945d029b26ef32fd154d4fcb1e0ff79015aa32d..b5be4ff616ff137b698e402fa224839dd8ba4c7e 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -1365,6 +1365,7 @@ void ivas_mdct_core_reconstruct( float *synthFB; /* TCX */ float xn_buf[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 xn_buf_fx[2040] = { 0 }; int16_t tcx_offset[CPE_CHANNELS]; int16_t tcx_offsetFB[CPE_CHANNELS]; int16_t left_rect[CPE_CHANNELS]; @@ -1413,10 +1414,118 @@ void ivas_mdct_core_reconstruct( if ( !skip_decoding ) { #ifdef IVAS_FLOAT_FIXED + // + Word16 synth_fx[2040], synthFB_fx[2040]; + Word16 q_x = Q11, q_win = -2; + Word32 x_fx[1200]; + Word16 x_e; + + FOR(Word16 i = 0; i < s_min(s_max(s_max(st->hIGFDec->infoIGFStopLine, s_max(L_frameTCX[ch], L_spec[ch])), L_frame[ch]), 1200); i++) { + x_fx[i] = (Word32)(x[ch][k][i] * (1 << q_x)); + } + x_e = 31 - q_x; + st->hIGFDec->virtualSpec_e = x_e; + IF ( NE_16(st->igf, 0) ) + FOR(Word16 i = 0; i < s_min(st->hIGFDec->infoIGFStopLine - st->hIGFDec->infoIGFStartLine, 856); i++) { + st->hIGFDec->virtualSpec_fx[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i] = (Word32)(st->hIGFDec->virtualSpec_float[st->hIGFDec->infoIGFStartLine - IGF_START_MN + i] * (1 << (31 - st->hIGFDec->virtualSpec_e))); + } - decoder_tcx_imdct_fx( st, L_frame_global[ch], L_frame_globalTCX[ch], L_spec[ch], tcx_offset[ch], tcx_offsetFB[ch], L_frame[ch], L_frameTCX[ch], left_rect[ch], &x[ch][k][0], xn_buf, + FOR( Word16 ind = 0; ind < 320; ind++ ) + { + st->hTcxDec->syn_Overl[ind] = (Word16)(st->hTcxDec->syn_Overl_float[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 320; ind++) { + st->hTcxDec->syn_Overl_TDAC[ind] = (Word16)(st->hTcxDec->syn_Overl_TDAC_float[ind] / (1<<(-q_win))); + } + FOR( Word16 ind = 0; ind < 480; ind++ ) + { + st->hTcxDec->syn_OverlFB[ind] = (Word16)(st->hTcxDec->syn_OverlFB_float[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 480; ind++) { + st->hTcxDec->syn_Overl_TDACFB[ind] = (Word16)(st->hTcxDec->syn_Overl_TDACFB_float[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 640; ind++) { + st->hHQ_core->old_out_LB_fx[ind] = (Word16)(st->hHQ_core->old_outLB[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 17; ind++) { + st->old_Aq_12_8_fx_32[ind] = (Word32)(st->old_Aq_12_8[ind] * (1<<28)); + } + FOR( Word16 ind = 0; ind < M + 1; ind++ ) + { + st->old_Aq_12_8_fx[ind] = (Word16) ( st->old_Aq_12_8[ind] * 4096.f ); + } + FOR(Word16 ind = 0; ind < 320; ind++) { + st->hTcxDec->old_syn_Overl[ind] = (Word16)(st->hTcxDec->old_syn_Overl_float[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 320; ind++) { + st->hTcxDec->syn_Overl_TDAC[ind] = (Word16)(st->hTcxDec->syn_Overl_TDAC_float[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 480; ind++) { + st->hTcxDec->syn_OverlFB[ind] = (Word16)(st->hTcxDec->syn_OverlFB_float[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < 320; ind++) { + st->hTcxDec->syn_Overl[ind] = (Word16)(st->hTcxDec->syn_Overl_float[ind] / (1<<(-q_win))); + } + st->hTcxDec->conceal_eof_gain = (Word16)(st->hTcxDec->conceal_eof_gain_float * 16384.f); + st->last_concealed_gain_syn_deemph = (Word16)(st->last_concealed_gain_syn_deemph_float * 32767.f); + float maxim = 0; + IF(st->hFdCngDec && st->hFdCngDec->hFdCngCom) { + FOR(Word16 ind = 0; ind < FFTCLDFBLEN; ind++) + { + maxim = fmaxf(maxim, fabsf(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[ind])); + } + st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 0; + st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31; + IF(L_abs((Word32)maxim)!=0) st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = norm_l((Word32)maxim); + IF(L_abs((Word32)maxim)!=0) st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 31 - norm_l((Word32)maxim); + FOR(Word16 ind = 0; ind < FFTCLDFBLEN; ind++) + { + st->hFdCngDec->hFdCngCom->cngNoiseLevel[ind] = (Word32)(st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[ind] * (1LL<<(31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp))); + } + st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = float_to_fix16(st->hFdCngDec->hFdCngCom->likelihood_noisy_speech_flt, 15); + } + FOR(Word16 ind = 0; ind < 960; ind++) { + st->hHQ_core->old_out_fx[ind] = (Word16)(st->hHQ_core->old_out[ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < L_frame_global[ch]; ind++) { + synth_fx[k * L_frame[ch] + ind] = (Word16)(synth[k * L_frame[ch] + ind] / (1<<(-q_win))); + } + FOR(Word16 ind = 0; ind < L_frame_globalTCX[ch]; ind++) { + synthFB_fx[k * L_frameTCX[ch] + ind] = (Word16)(synthFB[k * L_frameTCX[ch] + ind] / (1<<(-q_win))); + } + + decoder_tcx_imdct_fx( st, L_frame_global[ch], L_frame_globalTCX[ch], L_spec[ch], tcx_offset[ch], tcx_offsetFB[ch], L_frame[ch], L_frameTCX[ch], left_rect[ch], &x_fx[0], q_x, xn_buf_fx, q_win, ( ( hCPE->nchan_out == 1 && st->hTcxDec->kernel_type[k] == MDST_IV ) || st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ? MDCT_IV : st->hTcxDec->kernel_type[k], - fUseTns[ch][k], &synth[k * L_frame[ch]], &synthFB[k * L_frameTCX[ch]], bfi, k, 0 ); + fUseTns[ch][k], &synth_fx[k * L_frame[ch]], &synthFB_fx[k * L_frameTCX[ch]], bfi, k, 0 ); + + IF(st->igf) me2f_buf(x_fx, x_e, x[ch][k], s_max(st->hIGFDec->infoIGFStopLine, s_max(L_frameTCX[ch], L_spec[ch]) ) ); + + FOR(Word16 ind = 0; ind < 17; ind++) { + st->old_Aq_12_8[ind] = (float)(st->old_Aq_12_8_fx[ind]) / (float)(1<<12); + } + FOR(Word16 ind = 0; ind < 640; ind++) { + st->hHQ_core->old_outLB[ind] = (float)st->hHQ_core->old_out_LB_fx[ind] * (1<<(-q_win)); + } + FOR(Word16 ind = 0; ind < 960; ind++) { + st->hHQ_core->old_out[ind] = (float)st->hHQ_core->old_out_fx[ind] * (1<<(-q_win)); + } + FOR(Word16 ind = 0; ind < L_frame_global[ch]; ind++) { + synth[k * L_frame[ch] + ind] = (float)synth_fx[k * L_frame[ch] + ind] * (1<<(-q_win)); + } + FOR(Word16 ind = 0; ind < L_frame_globalTCX[ch]; ind++) { + synthFB[k * L_frameTCX[ch] + ind] = (float)synthFB_fx[k * L_frameTCX[ch] + ind] * (1<<(-q_win)); + } + IF ( EQ_16(st->hTcxCfg->last_aldo, 0) ) FOR(Word16 ind = 0; ind < L_FRAME32k / 2; ind++) { + st->hTcxDec->syn_Overl_float[ind] = (float)st->hTcxDec->syn_Overl[ind] * (1<<(-q_win)); + } + IF ( EQ_16(st->hTcxCfg->last_aldo, 0) ) FOR(Word16 ind = 0; ind < L_FRAME_MAX / 2; ind++) { + st->hTcxDec->syn_OverlFB_float[ind] = (float)st->hTcxDec->syn_OverlFB[ind] * (1<<(-q_win)); + } + st->hTcxDec->tcxltp_third_last_pitch_float = fix_to_float(st->hTcxDec->tcxltp_third_last_pitch, 16); + st->hTcxDec->tcxltp_second_last_pitch_float = fix_to_float(st->hTcxDec->tcxltp_second_last_pitch, 16); + st->old_fpitch_float = fix_to_float(st->old_fpitch, 16); + st->old_fpitchFB_float = fix_to_float(st->old_fpitchFB, 16); + // #else decoder_tcx_imdct( st, L_frame_global[ch], L_frame_globalTCX[ch], L_spec[ch], tcx_offset[ch], tcx_offsetFB[ch], L_frame[ch], L_frameTCX[ch], left_rect[ch], &x[ch][k][0], xn_buf, diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 2220763db516ce5d3f0d29e59cc3064ce65db6c7..98164ee5f0dda3010bc7ccb3d0c9f231d120001d 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -2208,6 +2208,7 @@ typedef struct Decoder_State float old_Aq_12_8[M + 1]; /* old Aq[] for core switching */ Word16 old_Aq_12_8_fx[M + 1]; /* Q12 old Aq[] for core switching */ + Word32 old_Aq_12_8_fx_32[M + 1]; /* Q28 old Aq[] for core switching */ float old_Es_pred; /* old Es_pred for core switching */ Word16 old_Es_pred_fx; /* old Es_pred for core switching */