diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-10-21 19:05:50 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-10-21 19:05:50 +0400 |
commit | 44a030deedf1105613417a4f42507d6602a3637c (patch) | |
tree | c66ac53e75bd99c2db36d7ec81e675ffdc46504c /silk/float | |
parent | 1fad3048af514f3abc6e70f844af3861ebf4ffca (diff) |
Limits how fast the CBR gain multiplier can increase
This fixes an overflow that was caused by having a huge gain
Diffstat (limited to 'silk/float')
-rw-r--r-- | silk/float/encode_frame_FLP.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c index a695d8a1..9ee6b44a 100644 --- a/silk/float/encode_frame_FLP.c +++ b/silk/float/encode_frame_FLP.c @@ -94,7 +94,8 @@ opus_int silk_encode_frame_FLP( silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; - opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_Q10, gainMult_lower, gainMult_upper; + opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; + opus_int16 gainMult_Q8; opus_int16 ec_prevLagIndex_copy; opus_int ec_prevSignalType_copy; opus_int8 LastGainIndex_copy2; @@ -181,7 +182,7 @@ TOC(NSQ) } else { /* Loop over quantizer and entroy coding to control bitrate */ maxIter = 5; - gainMult_Q10 = SILK_FIX_CONST( 1, 10 ); + gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); found_lower = 0; found_upper = 0; for( iter = 0; ; iter++ ) { @@ -234,7 +235,7 @@ TOC(ENCODE_PULSES) if( nBits > maxBits ) { found_upper = 1; nBits_upper = nBits; - gainMult_upper = gainMult_Q10; + gainMult_upper = gainMult_Q8; if( found_lower == 0 && iter >= 3 ) { /* Adjust the quantizer's rate/distortion tradeoff */ sEncCtrl.Lambda *= 1.5f; @@ -242,7 +243,7 @@ TOC(ENCODE_PULSES) } else if( nBits < maxBits - 5 ) { found_lower = 1; nBits_lower = nBits; - gainMult_lower = gainMult_Q10; + gainMult_lower = gainMult_Q8; /* Copy part of the output state */ silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); @@ -256,25 +257,26 @@ TOC(ENCODE_PULSES) if( ( found_lower & found_upper ) == 0 ) { /* Adjust gain according to high-rate rate/distortion curve */ opus_int32 gain_factor_Q16;
- gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
+ gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); + gain_factor_Q16 = silk_min_32(gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
if( nBits > maxBits ) { gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); } - gainMult_Q10 = silk_SMULWW( gainMult_Q10, gain_factor_Q16 );
+ gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
} else { /* Adjust gain by interpolating */ - gainMult_Q10 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); + gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q10 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q10 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); + if( gainMult_Q8 > gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = gainMult_lower + silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); } else - if( gainMult_Q10 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q10 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); + if( gainMult_Q8 < gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = gainMult_upper - silk_RSHIFT32( gainMult_upper - gainMult_lower, 2 ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWW( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q10 ), 6 ); + pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); } psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; |