diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 0e829e59ba926579b09a14ca5d99ffdea6193729..2548e7470a51a8e82af0888342023321c4a53d1a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -2729,6 +2729,12 @@ void time_envelop_shaping_fx( const Word16 L, /* i : frame length */ Word16 *Q_synth ); +void time_envelop_shaping_ivas_fx( + Word16 werr[], /* i/o: SHB synthesis Q_synth*/ + Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ + const Word16 L, /* i : frame length */ + Word16 *Q_synth ); + void time_reduce_pre_echo_fx( const Word16 *synth, /* i : ACELP core synthesis Q_syn*/ Word16 *error, /* i/o: SHB BWE synthesis Q0*/ diff --git a/lib_com/swb_bwe_com_fx.c b/lib_com/swb_bwe_com_fx.c index dd0c8aa301f34dc8f9b2df4d4f3e8f171bb61678..2c862c1e2cb79371512480d3c8dee6cedab59563 100644 --- a/lib_com/swb_bwe_com_fx.c +++ b/lib_com/swb_bwe_com_fx.c @@ -2213,6 +2213,97 @@ void time_envelop_shaping_fx( L_tmp = Mult_32_16( SWB_tenv[i], tmp_ener ); /*Q(29-exp) */ tmp = round_fx( L_tmp ); /*Q(13-exp) */ + FOR( j = 0; j < L / 4; j++ ) + { +#ifdef BASOP_NOGLOB + *pit = round_fx_sat( L_shl_sat( L_mult( tmp, *pit ), sub( exp, 1 ) ) ); /*Q(13-exp+1)->Q(14-exp)->Qsyn-3 */ +#else + *pit = round_fx( L_shl( L_mult( tmp, *pit ), sub( exp, 1 ) ) ); /*Q(13-exp+1)->Q(14-exp)->Qsyn-3 */ +#endif + move16(); + pit++; + } + } + } + + return; +} + +void time_envelop_shaping_ivas_fx( + Word16 werr[], /* i/o: SHB synthesis Q_synth*/ + Word32 SWB_tenv[], /* i/o: frequency envelope Q15*/ + const Word16 L, /* i : frame length */ + Word16 *Q_synth ) +{ + Word16 *pit; + Word32 Energy; + Word16 i, j; + Word16 tmp_ener, Energy_16; + Word64 Energy_64; + Word16 exp_L, exp, frac, tmp, inv_L, w_tmp, Energy_Q; + Word32 L_tmp; + + pit = werr; + exp_L = norm_s( L ); + inv_L = div_s( shl( 1, sub( 14, exp_L ) ), L ); /*Q(29-exp_L) */ + FOR( i = 0; i < SWB_TENV; i++ ) + { + Energy_64 = L_deposit_l( 0 ); + FOR( j = 0; j < L / 4; j++ ) + { + Energy_64 = W_mac0_16_16( Energy_64, *pit, *pit ); /*(2*Q_synth) */ + pit++; + } + w_tmp = W_norm( Energy_64 ); + Energy_64 = W_shl( Energy_64, w_tmp ); + Energy = W_extract_h( Energy_64 ); /*2*Q_synth + w_tmp -32*/ + Energy_Q = sub( add( shl( ( *Q_synth ), 1 ), w_tmp ), 32 ); + Energy = Mult_32_16( Energy, inv_L ); /*Q(29-exp_L-15) -> Q(-exp_L+14+2*Q_synth+w_tmp-32) */ + Energy_16 = 0; + move16(); + /*exp = 31-(-exp_L+14 +(2*(*Q_synth)+w_tmp-32)); */ + exp = sub( 17, sub( Energy_Q, exp_L ) ); + + IF( Energy != 0 ) + { + exp = norm_l( Energy ); + frac = extract_h( L_shl( Energy, exp ) ); + /*exp = sub(exp, 30-(-exp_L+14-2+(2*(*Q_synth)+w_tmp-32))); */ + exp = sub( exp, sub( 30, add( sub( Energy_Q, exp_L ), 14 - 2 ) ) ); + + tmp = div_s( 16384, frac ); + L_tmp = L_deposit_h( tmp ); + Energy = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp) */ + Energy_16 = round_fx( L_shl( Energy, sub( exp, 15 ) ) ); /*Q0 */ + } + + test(); +#ifdef BASOP_NOGLOB + IF( LT_32( SWB_tenv[i], 65536 /* 2 in Q15 */ ) && LT_32( Energy, L_shl_sat( SWB_tenv[i], sub( 16, exp ) ) ) ) +#else + IF( LT_32( SWB_tenv[i], 65536 /* 2 in Q15 */ ) && LT_32( Energy, L_shl( SWB_tenv[i], sub( 16, exp ) ) ) ) +#endif + { + *Q_synth = add( *Q_synth, 3 ); + move16(); + } + ELSE + { + pit -= shr( L, 2 ); + tmp_ener = 0; + move16(); + exp = 0; + move16(); + + IF( Energy_16 != 0 ) + { + exp = norm_s( Energy_16 ); + tmp_ener = div_s( shl( 1, sub( 14, exp ) ), Energy_16 ); /*Q(29-exp) */ + } + + L_tmp = Mult_32_16( SWB_tenv[i], tmp_ener ); /*Q(29-exp) */ + tmp = round_fx( L_tmp ); /*Q(13-exp) */ + FOR( j = 0; j < L / 4; j++ ) { #ifdef BASOP_NOGLOB diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c index 90a2a0130ca91853e5176a91345515fcaf50ffec..22b2dc73127cba64fa7078cc1e5b286162187675 100644 --- a/lib_dec/swb_bwe_dec.c +++ b/lib_dec/swb_bwe_dec.c @@ -579,7 +579,8 @@ Word16 swb_bwe_dec_fx32( } /* time envelope shaping when the current frame is TRANSIENT frame */ - time_envelop_shaping_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); + time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); + Q_syn_hb = sub( Q_syn_hb, 3 ); hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3];