Loading lib_com/edct_fx.c +3 −3 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -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; } Loading Loading @@ -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 { Loading lib_com/ivas_prot_fx.h +7 −4 Original line number Diff line number Diff line Loading @@ -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 */ Loading lib_com/lag_wind.c +54 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading lib_com/lpc_tools.c +72 −0 Original line number Diff line number Diff line Loading @@ -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 /*---------------------------------------------------------------------* Loading lib_com/lpc_tools_fx.c +108 −0 Original line number Diff line number Diff line Loading @@ -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<len/2; i++ ) { y[i] = mult_r(x[i], wind[i]); move16(); } FOR( ; i<len; i++ ) { y[i] = mult_r(x[i], wind[len-i-1]); move16(); } } ELSE /* assymetric window */ { FOR (i = 0; i < len; i++) { y[i] = mult_r(x[i], wind[i]); move16(); } } /* calculate energy of signal */ L_sum = L_deposit_h(16); /* sqrt(256), avoid overflow after rounding */ FOR (i=0; i<len; i+=2) { L_tmp = L_mult0(y[i], y[i]); L_tmp = L_and(L_tmp, ~(128-1)); L_tmp = L_mac0(L_tmp, y[i+1], y[i+1]); L_tmp = L_shr(L_tmp, 7); L_sum = L_add(L_sum, L_tmp); } /* scale signal to avoid overflow in autocorrelation */ norm = norm_l(L_sum); shift = sub(4, shr(norm, 1)); IF (shift > 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 /***************************************************************************** * * Loading Loading
lib_com/edct_fx.c +3 −3 Original line number Diff line number Diff line Loading @@ -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]; Loading @@ -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; } Loading Loading @@ -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 { Loading
lib_com/ivas_prot_fx.h +7 −4 Original line number Diff line number Diff line Loading @@ -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 */ Loading
lib_com/lag_wind.c +54 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
lib_com/lpc_tools.c +72 −0 Original line number Diff line number Diff line Loading @@ -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 /*---------------------------------------------------------------------* Loading
lib_com/lpc_tools_fx.c +108 −0 Original line number Diff line number Diff line Loading @@ -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<len/2; i++ ) { y[i] = mult_r(x[i], wind[i]); move16(); } FOR( ; i<len; i++ ) { y[i] = mult_r(x[i], wind[len-i-1]); move16(); } } ELSE /* assymetric window */ { FOR (i = 0; i < len; i++) { y[i] = mult_r(x[i], wind[i]); move16(); } } /* calculate energy of signal */ L_sum = L_deposit_h(16); /* sqrt(256), avoid overflow after rounding */ FOR (i=0; i<len; i+=2) { L_tmp = L_mult0(y[i], y[i]); L_tmp = L_and(L_tmp, ~(128-1)); L_tmp = L_mac0(L_tmp, y[i+1], y[i+1]); L_tmp = L_shr(L_tmp, 7); L_sum = L_add(L_sum, L_tmp); } /* scale signal to avoid overflow in autocorrelation */ norm = norm_l(L_sum); shift = sub(4, shr(norm, 1)); IF (shift > 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 /***************************************************************************** * * Loading