diff options
author | Koen Vos <koenvos74@gmail.com> | 2014-06-20 04:07:55 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2014-06-20 04:57:09 +0400 |
commit | 9c7193e4f956e230d919f604df27ea4b13b62370 (patch) | |
tree | 3c0a13651310d142ae43bd3c27565de8ce09cffb /silk/CNG.c | |
parent | a88d8365d42e5369777afa496b43ea88a1aa9106 (diff) |
Fixes CNG to address the DTX issue reported by Gonzalo Mariano
- Bug fix: the CNG synthesis filter output consisted of only the prediction
values, now added the input to that.
- CNG excitation level now takes into account the level from the PLC (since
both PLC and CNG can be active at the same time).
- CNG is now called before PLC_glue() to smoothen the transition out of CNG.
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
Diffstat (limited to 'silk/CNG.c')
-rw-r--r-- | silk/CNG.c | 15 |
1 files changed, 10 insertions, 5 deletions
@@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. /* Generates excitation for CNG LPC synthesis */ static OPUS_INLINE void silk_CNG_exc( - opus_int32 residual_Q10[], /* O CNG residual signal Q10 */ + opus_int32 exc_Q10[], /* O CNG excitation signal Q10 */ opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ opus_int32 Gain_Q16, /* I Gain to apply */ opus_int length, /* I Length */ @@ -55,7 +55,7 @@ static OPUS_INLINE void silk_CNG_exc( idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); silk_assert( idx >= 0 ); silk_assert( idx <= CNG_BUF_MASK_MAX ); - residual_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); + exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); } *rand_seed = seed; } @@ -85,7 +85,7 @@ void silk_CNG( ) { opus_int i, subfr; - opus_int32 sum_Q6, max_Gain_Q16; + opus_int32 sum_Q6, max_Gain_Q16, gain_Q16; opus_int16 A_Q12[ MAX_LPC_ORDER ]; silk_CNG_struct *psCNG = &psDec->sCNG; SAVE_STACK; @@ -129,7 +129,12 @@ void silk_CNG( ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); /* Generate CNG excitation */ - silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed ); + gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] ); + gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 ); + gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); + gain_Q16 = silk_max_32( gain_Q16, 0 ); + gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 ); + silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed ); /* Convert CNG NLSF to filter representation */ silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); @@ -162,7 +167,7 @@ void silk_CNG( /* Update states */ CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); - frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( sum_Q6, 6 ) ); + frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) ); } silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); } else { |