diff --git a/lib_com/frame_ener.c b/lib_com/frame_ener.c index 721249fb6118ad5a24c540033cbdf53838560ef1..4d1891efa7bd786d766fd78341c7901f1a7f5ee7 100644 --- a/lib_com/frame_ener.c +++ b/lib_com/frame_ener.c @@ -86,6 +86,59 @@ void fer_energy( return; } +#ifdef IVAS_FLOAT_FIXED +void fer_energy_fx( + const Word16 L_frame, /* i : frame length */ + const Word16 clas, /* i : frame classification */ + const Word32 *synth, /* i : synthesized speech at Fs = 12k8 Hz */ + const Word16 q_synth, /* i : synthesized speech at Fs = 12k8 Hz */ + const Word16 pitch, /* i : pitch period */ + Word32 *enr, /* o : pitch-synchronous or half_frame energy */ + const Word16 offset /* i : speech pointer offset (0 or L_frame) */ +) +{ + Word16 len, shift, exp; + const Word32 *pt_synth; + Word16 enr_tmp; + Word64 W_tmp; + + test(); + test(); + IF( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */ + { + len = ( pitch ); /* pitch value */ + + pt_synth = synth; + IF( NE_16( offset, 0 ) ) + { + pt_synth = synth + L_frame - len; + } + + emaximum_32fx( q_synth, pt_synth, len, enr ); /* pitch synchronous E */ + } + ELSE + { + pt_synth = synth; + IF( NE_16( offset, 0 ) ) + { + pt_synth = synth + shr( L_frame, 1 ); + } + + W_tmp = 0; + for ( int i = 0; i < shr( L_frame, 1 ); i++ ) + { + W_tmp = W_add( W_tmp, W_mult0_32_32( pt_synth[i], pt_synth[i] ) ); // Q = q_synth * 2 + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); // Q = q_synth * 2 + shift + *enr = W_extract_h( W_tmp ); // Q = q_synth * 2 + shift - 32 + + enr_tmp = BASOP_Util_Divide3216_Scale( *enr, shr( L_frame, 1 ) /*Q0*/, &exp ); + *enr = L_shl( L_deposit_l( enr_tmp ), 5 ); + } + return; +} +#endif // IVAS_FLOAT_FIXED /*------------------------------------------------------------------------* * frame_energy() diff --git a/lib_com/prot_fx1.h b/lib_com/prot_fx1.h index 91b003e18eda396ba19c443e51a68fb30b5291ea..e8c168a83e8df8e6da5829cfa5312a3fa37453a1 100644 --- a/lib_com/prot_fx1.h +++ b/lib_com/prot_fx1.h @@ -247,6 +247,12 @@ Word16 emaximum_fx( /* o : return index with max energy valu const Word16 lvec, /* i : length of input vector Q0 */ Word32 *ener_max /* o : maximum energy value Q0 */ ); +Word16 emaximum_32fx( /* o : return index with max energy value in vector Q0 */ + const Word16 Qvec, /* i : Q of input vector Q0 */ + const Word32 *vec, /* i : input vector Qx */ + const Word16 lvec, /* i : length of input vector Q0 */ + Word32 *ener_max /* o : maximum energy value Q0 */ +); Word32 Mean32( /* o : mean of the elements of the vector */ const Word32 in[], /* i : input vector */ const Word16 L /* i : length of input vector */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 5e5d17d62c3eefcb395b070406790a0c85abc431..667d29dc0c7b24f243f1288bbf033de39d08e0c8 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -1335,6 +1335,16 @@ Word16 gsc_gainQ_fx( ); //frame_ener.c +void fer_energy_fx( + const Word16 L_frame, /* i : frame length */ + const Word16 clas, /* i : frame classification */ + const Word32 *synth, /* i : synthesized speech at Fs = 12k8 Hz */ + const Word16 q_synth, /* i : synthesized speech at Fs = 12k8 Hz */ + const Word16 pitch, /* i : pitch period */ + Word32 *enr, /* o : pitch-synchronous or half_frame energy */ + const Word16 offset /* i : speech pointer offset (0 or L_frame) */ +); + Word16 frame_ener_fx( const Word16 L_frame, /* i : length of the frame */ const Word16 clas, /* i : frame classification */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 81e23737d15cafd2844d1024eca2d860fd36a180..d44591aa0f4a07e45fae3d75161f9078371caf8c 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -1648,6 +1648,44 @@ Word16 emaximum_fx( /* o : return index with max energy value in return ind; } + +Word16 emaximum_32fx( /* o : return index with max energy value in vector Q0 */ + const Word16 Qvec, /* i : Q of input vector Q0 */ + const Word32 *vec, /* i : input vector Qx */ + const Word16 lvec, /* i : length of input vector Q0 */ + Word32 *ener_max /* o : maximum energy value Q0 */ +) +{ + Word16 j, ind; + Word64 W_tmp, W_tmp1; + Word64 emax; + + emax = W_mult0_32_32( vec[0], vec[0] ); + ind = 0; + move16(); + + FOR( j = 1; j < lvec; j++ ) + { + W_tmp = W_mult0_32_32( vec[j], vec[j] ); + W_tmp1 = W_sub( W_tmp, emax ); + IF( GT_64( W_tmp1, 0 ) ) + { + ind = j; + move16(); + } + emax = GT_64( emax, W_tmp ) ? emax : W_tmp; + } + +#ifdef BASOP_NOGLOB + *ener_max = W_extract_l( W_shr( emax, add( Qvec, Qvec ) ) ); +#else /* BASOP_NOGLOB */ + *ener_max = L_shr( emax, add( Qvec, Qvec ) ); +#endif /* BASOP_NOGLOB */ + move64(); + + return ind; +} + /*-------------------------------------------------------------------* * mean32: * diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index 56668cd46ac0c83b8708c8f91f464f008655fda8..3dee78be81ed2ccf70c5d919370a5b9ddeae973f 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -597,6 +597,26 @@ void stereo_tcx_core_dec( if ( bfi && st->last_core != ACELP_CORE ) { /* Update FEC_scale_syn parameters */ +#ifdef IVAS_FLOAT_FIXED + Word32 synth_fx[L_FRAME48k], enr_old_fx; + Word16 q_synth = 11, old_fpitch_fx; + for ( int p = 0; p < st->L_frame; p++ ) + { + synth_fx[p] = (Word32) ( synth[p] * ( 1u << q_synth ) ); + } + old_fpitch_fx = (Word16) ( st->old_fpitch_float + 0.5f ); + + IF ( hTcxLtpDec->tcxltp_gain_float == 0 ) + { + fer_energy_fx( st->L_frame, UNVOICED, synth_fx, q_synth, shr( st->L_frame, 1 ), &enr_old_fx, st->L_frame ); + } + ELSE + { + fer_energy_fx( st->L_frame, st->clas_dec, synth_fx, q_synth, old_fpitch_fx, &enr_old_fx, st->L_frame ); + } + + st->enr_old = (float) enr_old_fx; +#else if ( hTcxLtpDec->tcxltp_gain_float == 0 ) { fer_energy( st->L_frame, UNVOICED, synth, (float) ( st->L_frame / 2 ), &st->enr_old, st->L_frame ); @@ -605,6 +625,7 @@ void stereo_tcx_core_dec( { fer_energy( st->L_frame, st->clas_dec, synth, st->old_fpitch_float, &st->enr_old, st->L_frame ); } +#endif // IVAS_FLOAT_FIXED } if ( !bfi && st->clas_dec >= VOICED_TRANSITION && st->clas_dec < INACTIVE_CLAS )