summaryrefslogtreecommitdiff
path: root/silk/LPC_inv_pred_gain.c
diff options
context:
space:
mode:
authorKoen Vos <koen.vos@skype.net>2011-12-13 14:47:31 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2011-12-13 14:47:31 -0500
commitbf75c8ec4d0dded188bc7793de6da56c7ff0be1c (patch)
treec21bb05faf0a203b73e8f8aae90fc63dac27625d /silk/LPC_inv_pred_gain.c
parent6619a736376221f2782cecff55d051c3ecfc2ff7 (diff)
downloadopus-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.c53
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