diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index 96d07e7ef305ed4534d8dd4a3ae338a537a7dbda..e4d84ef23c38a6584b694485cb3082d43667ff37 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -3309,6 +3309,9 @@ void GenShapedSHBExcitation_ivas_enc_fx( move16(); move16(); + scale_sig( White_exc16k, L_FRAME16k, -1 /* guard bit to prevent saturation in deemph*/ ); + Q_White_exc16k = sub( Q_White_exc16k, 1 ); + Word16 tbe_demph_fx = shl_sat( *tbe_demph, sub( Q_White_exc16k, *Q_bwe_exc ) ); // Q_White_exc16k deemph_fx( White_exc16k, PREEMPH_FAC, L_FRAME16k, &tbe_demph_fx ); diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 9d0f16ee91b0c1eb8fbef1985c7bd49afa832300..b001f86936e2b65ac3582c22c0d37839c1f9b790 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -77,7 +77,8 @@ static void EstimateSHBGainShape_fx( const Word16 length, const Word16 Q_synSHB, Word16 *subgain, const Word16 *subwin, - Word16 *n_subfr_saturation ); + Word16 *n_subfr_saturation, + const Flag limit_min_gain ); static Word32 pow_off_pk_fx( Word16 a[], Word16 len, Word16 step ); @@ -1072,7 +1073,7 @@ void wb_tbe_enc_fx( Copy( shaped_wb_excitation + L_FRAME16k / 4, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD / 4 ); EstimateSHBGainShape_fx( SHB_OVERLAP_LEN / 2, hb_frame, Q_ns, - shaped_wb_excitation, Q_bwe_exc_ext, GainShape, subwin_wb_fx, NULL ); + shaped_wb_excitation, Q_bwe_exc_ext, GainShape, subwin_wb_fx, NULL, 1 ); /* Gain frame adjustment factor */ test(); @@ -1707,7 +1708,7 @@ void wb_tbe_enc_ivas_fx( Copy( shaped_wb_excitation + L_FRAME16k / 4, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD / 4 ); EstimateSHBGainShape_fx( SHB_OVERLAP_LEN / 2, hb_frame, Q_ns, - shaped_wb_excitation, Q_bwe_exc_ext, GainShape, subwin_wb_fx, NULL ); + shaped_wb_excitation, Q_bwe_exc_ext, GainShape, subwin_wb_fx, NULL, 1 ); /* Gain frame adjustment factor */ test(); @@ -2552,7 +2553,7 @@ void swb_tbe_enc_fx( n_subfr_saturation = 0; move16(); EstimateSHBGainShape_fx( SHB_OVERLAP_LEN, shb_frame_fx, Q_shb, shaped_shb_excitation_fx, - Q_bwe_exc, GainShape_fx, subwin_shb_fx, &n_subfr_saturation ); + Q_bwe_exc, GainShape_fx, subwin_shb_fx, &n_subfr_saturation, 1 ); /* Gain shape BWS/high band low energy fix */ IF( LT_16( hBWE_TD->cldfbHBLT, 8192 /*1.0f Q13*/ ) ) /* cldfbHBLT in Q13 */ @@ -3857,7 +3858,7 @@ void swb_tbe_enc_ivas_fx( n_subfr_saturation = 0; move16(); EstimateSHBGainShape_fx( SHB_OVERLAP_LEN, shb_frame_fx, Q_shb, shaped_shb_excitation_fx, - Q_bwe_exc, GainShape_fx, subwin_shb_fx, &n_subfr_saturation ); + Q_bwe_exc, GainShape_fx, subwin_shb_fx, &n_subfr_saturation, 0 ); test(); IF( EQ_32( st_fx->extl_brate, SWB_TBE_1k10 ) || EQ_32( st_fx->extl_brate, SWB_TBE_1k75 ) ) @@ -4931,14 +4932,15 @@ static Word32 pow_off_pk_corrected_fx( Word16 a[], Word16 len, Word16 step ) /*--------------------------------------------------------------------------*/ static void EstimateSHBGainShape_fx( - const Word16 length, /* i : SHB overlap length */ - const Word16 *oriSHB, /* i : target original SHB frame Q(Q_oriSHB) */ - const Word16 Q_oriSHB, /* i : Q of target original SHB frame */ - const Word16 *synSHB, /* i : shaped SHB excitation Q(Q_synSHB) */ - const Word16 Q_synSHB, /* i : Q of shaped SHB excitation */ - Word16 *subgain, /* o : estimate of gain shape Q15 */ - const Word16 *subwin, /* i : SHB subframe window Q15 */ - Word16 *n_subfr_saturation /* o : Number of subframes which saturated while calculating oriNrg */ + const Word16 length, /* i : SHB overlap length */ + const Word16 *oriSHB, /* i : target original SHB frame Q(Q_oriSHB) */ + const Word16 Q_oriSHB, /* i : Q of target original SHB frame */ + const Word16 *synSHB, /* i : shaped SHB excitation Q(Q_synSHB) */ + const Word16 Q_synSHB, /* i : Q of shaped SHB excitation */ + Word16 *subgain, /* o : estimate of gain shape Q15 */ + const Word16 *subwin, /* i : SHB subframe window Q15 */ + Word16 *n_subfr_saturation, /* o : Number of subframes which saturated while calculating oriNrg */ + const Flag limit_min_gain /* i : gain shape limiting flag */ ) { const Word16 *skip; @@ -5152,11 +5154,23 @@ static void EstimateSHBGainShape_fx( n = sub( 31, add( n, ( sub( 28, shl( n_max, 1 ) ) ) ) ); normFact = Isqrt_lc( L_sum_gain, &n ); - FOR( i = 0; i < num_gains; i++ ) + IF( limit_min_gain ) { - L_tmp = Mpy_32_16_1( normFact, subgain[i] ); /*Q(31-n) * Q(31-norm[i]) */ /* Q(30-n-n_max) */ - subgain[i] = s_max( round_fx_o( L_shl_o( L_tmp, add( n, n_max + 1 ), &Overflow ), &Overflow ), 3277 /*0.1f Q15*/ ); /* Q15 */ - move16(); + FOR( i = 0; i < num_gains; i++ ) + { + L_tmp = Mpy_32_16_1( normFact, subgain[i] ); /*Q(31-n) * Q(31-norm[i]) */ /* Q(30-n-n_max) */ + subgain[i] = s_max( round_fx_o( L_shl_o( L_tmp, add( n, n_max + 1 ), &Overflow ), &Overflow ), 3277 /*0.1f Q15*/ ); /* Q15 */ + move16(); + } + } + ELSE + { + FOR( i = 0; i < num_gains; i++ ) + { + L_tmp = Mpy_32_16_1( normFact, subgain[i] ); /*Q(31-n) * Q(31-norm[i]) */ /* Q(30-n-n_max) */ + subgain[i] = round_fx_o( L_shl_o( L_tmp, add( n, n_max + 1 ), &Overflow ), &Overflow ); /* Q15 */ + move16(); + } } return;