diff options
author | Koen Vos <koen.vos@skype.net> | 2011-12-13 14:47:31 -0500 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-12-13 14:47:31 -0500 |
commit | bf75c8ec4d0dded188bc7793de6da56c7ff0be1c (patch) | |
tree | c21bb05faf0a203b73e8f8aae90fc63dac27625d /silk/LPC_inv_pred_gain.c | |
parent | 6619a736376221f2782cecff55d051c3ecfc2ff7 (diff) | |
download | opus-bf75c8ec4d0dded188bc7793de6da56c7ff0be1c.tar.gz |
SILK fixes following last codec WG meeting
decoder:
- fixed incorrect scaling of filter states for the smallest quantization
step sizes
- NLSF2A now limits the prediction gain of LPC filters
encoder:
- increased damping of LTP coefficients in LTP analysis
- increased white noise fraction in noise shaping LPC analysis
- introduced maximum total prediction gain. Used by Burg's method to
exit early if prediction gain is exceeded. This improves packet
loss robustness and numerical robustness in Burg's method
- Prefiltered signal is now in int32 Q10 domain, from int16 Q0
- Increased max number of iterations in CBR gain control loop from 5 to 6
- Removed useless code from LTP scaling control
- Optimization: smarter LPC loop unrolling
- Switched default win32 compile mode to be floating-point
resampler:
- made resampler have constant delay of 0.75 ms; removed delay
compensation from silk code.
- removed obsolete table entries (~850 Bytes)
- increased downsampling filter order from 16 to 18/24/36 (depending on
frequency ratio)
- reoptimized filter coefficients
Diffstat (limited to 'silk/LPC_inv_pred_gain.c')
-rw-r--r-- | silk/LPC_inv_pred_gain.c | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/silk/LPC_inv_pred_gain.c b/silk/LPC_inv_pred_gain.c index 249da318..db529d14 100644 --- a/silk/LPC_inv_pred_gain.c +++ b/silk/LPC_inv_pred_gain.c @@ -38,24 +38,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* Compute inverse of LPC prediction gain, and */ /* test if LPC coefficients are stable (all poles within unit circle) */ -static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if unstable, otherwise 0 */ - opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */ - opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ - const opus_int order /* I Prediction order */ +static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */ + opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ + const opus_int order /* I Prediction order */ ) { opus_int k, n, mult2Q; - opus_int32 rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA; + opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA; opus_int32 *Aold_QA, *Anew_QA; Anew_QA = A_QA[ order & 1 ]; - *invGain_Q30 = ( 1 << 30 ); + invGain_Q30 = 1 << 30; for( k = order - 1; k > 0; k-- ) { /* Check for stability */ if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { - *invGain_Q30 = 0; - return 1; + return 0; } /* Set RC equal to negated AR coef */ @@ -72,9 +70,9 @@ static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if /* Update inverse gain */ /* invGain_Q30 range: [ 0 : 2^30 ] */ - *invGain_Q30 = silk_LSHIFT( silk_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 ); - silk_assert( *invGain_Q30 >= 0 ); - silk_assert( *invGain_Q30 <= ( 1 << 30 ) ); + invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); + silk_assert( invGain_Q30 >= 0 ); + silk_assert( invGain_Q30 <= ( 1 << 30 ) ); /* Swap pointers */ Aold_QA = Anew_QA; @@ -89,8 +87,7 @@ static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if /* Check for stability */ if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { - *invGain_Q30 = 0; - return 1; + return 0; } /* Set RC equal to negated AR coef */ @@ -101,16 +98,15 @@ static opus_int LPC_inverse_pred_gain_QA( /* O Returns 1 if /* Update inverse gain */ /* Range: [ 0 : 2^30 ] */ - *invGain_Q30 = silk_LSHIFT( silk_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 ); - silk_assert( *invGain_Q30 >= 0 ); - silk_assert( *invGain_Q30 <= 1<<30 ); + invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); + silk_assert( invGain_Q30 >= 0 ); + silk_assert( invGain_Q30 <= 1<<30 ); - return 0; + return invGain_Q30; } /* For input in Q12 domain */ -opus_int silk_LPC_inverse_pred_gain( /* O Returns 1 if unstable, otherwise 0 */ - opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */ +opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ const opus_int order /* I Prediction order */ ) @@ -118,30 +114,27 @@ opus_int silk_LPC_inverse_pred_gain( /* O Returns 1 if unstable opus_int k; opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; opus_int32 *Anew_QA; - opus_int32 DC_resp=0; + opus_int32 DC_resp = 0; Anew_QA = Atmp_QA[ order & 1 ]; /* Increase Q domain of the AR coefficients */ for( k = 0; k < order; k++ ) { DC_resp += (opus_int32)A_Q12[ k ]; - Anew_QA[ k ] = silk_LSHIFT( (opus_int32)A_Q12[ k ], QA - 12 ); + Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); } /* If the DC is unstable, we don't even need to do the full calculations */ if( DC_resp >= 4096 ) { - *invGain_Q30 = 0; - return 1; + return 0; } - return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order ); + return LPC_inverse_pred_gain_QA( Atmp_QA, order ); } #ifdef FIXED_POINT /* For input in Q24 domain */ -/* This function is only used by the fixed-point build */ -opus_int silk_LPC_inverse_pred_gain_Q24( /* O Returns 1 if unstable, otherwise 0 */ - opus_int32 *invGain_Q30, /* O Inverse prediction gain, Q30 energy domain */ - const opus_int32 *A_Q24, /* I Prediction coefficients, Q24 [order] */ +opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ + const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ const opus_int order /* I Prediction order */ ) { @@ -153,9 +146,9 @@ opus_int silk_LPC_inverse_pred_gain_Q24( /* O Returns 1 if unstabl /* Increase Q domain of the AR coefficients */ for( k = 0; k < order; k++ ) { - Anew_QA[ k ] = silk_RSHIFT( A_Q24[ k ], 24 - QA ); + Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA ); } - return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order ); + return LPC_inverse_pred_gain_QA( Atmp_QA, order ); } #endif |