shithub: opus

Download patch

ref: 54518c879a6541eab749bc19628f1795daaad1e3
parent: a26b2be2f922502b821e81e2cb084393f1ccf405
author: Koen Vos <[email protected]>
date: Mon Jan 30 20:51:22 EST 2012

Last part of the LPC work stabilization work discussed at the last meeting

Also adds the encoder part of commit ee8adbe701 as well as a few
minor cleanups.

--- a/silk/A2NLSF.c
+++ b/silk/A2NLSF.c
@@ -40,7 +40,6 @@
 
 /* Number of binary divisions, when not in low complexity mode */
 #define BIN_DIV_STEPS_A2NLSF_FIX      3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
-#define QPoly                        16
 #define MAX_ITERATIONS_A2NLSF_FIX    30
 
 /* Helper function for A2NLSF(..)                    */
@@ -61,8 +60,8 @@
 }
 /* Helper function for A2NLSF(..) */
 /* Polynomial evaluation          */
-static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in QPoly   */
-    opus_int32          *p,                     /* I    Polynomial, QPoly                       */
+static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16     */
+    opus_int32          *p,                     /* I    Polynomial, Q16                         */
     const opus_int32    x,                      /* I    Evaluation point, Q12                   */
     const opus_int      dd                      /* I    Order                                   */
 )
@@ -70,10 +69,10 @@
     opus_int   n;
     opus_int32 x_Q16, y32;
 
-    y32 = p[ dd ];                                  /* QPoly */
+    y32 = p[ dd ];                                  /* Q16 */
     x_Q16 = silk_LSHIFT( x, 4 );
     for( n = dd - 1; n >= 0; n-- ) {
-        y32 = silk_SMLAWW( p[ n ], y32, x_Q16 );    /* QPoly */
+        y32 = silk_SMLAWW( p[ n ], y32, x_Q16 );    /* Q16 */
     }
     return y32;
 }
@@ -88,19 +87,11 @@
     opus_int k;
 
     /* Convert filter coefs to even and odd polynomials */
-    P[dd] = silk_LSHIFT( 1, QPoly );
-    Q[dd] = silk_LSHIFT( 1, QPoly );
+    P[dd] = silk_LSHIFT( 1, 16 );
+    Q[dd] = silk_LSHIFT( 1, 16 );
     for( k = 0; k < dd; k++ ) {
-#if( QPoly < 16 )
-        P[ k ] = silk_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
-        Q[ k ] = silk_RSHIFT_ROUND( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], 16 - QPoly ); /* QPoly */
-#elif( Qpoly == 16 )
-        P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* QPoly*/
-        Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* QPoly*/
-#else
-        P[ k ] = silk_LSHIFT( -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
-        Q[ k ] = silk_LSHIFT( -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ], QPoly - 16 ); /* QPoly */
-#endif
+        P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ];    /* Q16 */
+        Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ];    /* Q16 */
     }
 
     /* Divide out zeros as we have that for even filter orders, */
--- a/silk/NLSF2A.c
+++ b/silk/NLSF2A.c
@@ -137,7 +137,7 @@
                 idx    = k;
             }
         }
-        maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 );       /* QA+1 -> Q12 */
+        maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 );                                          /* QA+1 -> Q12 */
 
         if( maxabs > silk_int16_MAX ) {
             /* Reduce magnitude of prediction coefficients */
@@ -153,32 +153,25 @@
     if( i == 10 ) {
         /* Reached the last iteration, clip the coefficients */
         for( k = 0; k < d; k++ ) {
-            a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */
+            a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) );  /* QA+1 -> Q12 */
             a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );
         }
     } else {
         for( k = 0; k < d; k++ ) {
-            a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );       /* QA+1 -> Q12 */
+            a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );                /* QA+1 -> Q12 */
         }
     }
 
-    for( i = 1; i <= MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
+    for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
         if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
             /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion   */
             /* on the unscaled coefficients, convert to Q12 and measure again                   */
-            silk_bwexpander_32( a32_QA1, d, 65536 - silk_SMULBB( 9 + i, i ) );            /* 10_Q16 = 0.00015 */
+            silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
             for( k = 0; k < d; k++ ) {
-                a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );  /* QA+1 -> Q12 */
+                a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );            /* QA+1 -> Q12 */
             }
         } else {
             break;
-        }
-    }
-
-    if( i > MAX_LPC_STABILIZE_ITERATIONS ) {
-        /* Reached the last iteration, set coefficients to zero */
-        for( k = 0; k < d; k++ ) {
-            a_Q12[ k ] = 0;
         }
     }
 }
--- a/silk/NLSF_decode.c
+++ b/silk/NLSF_decode.c
@@ -83,7 +83,7 @@
     /* Unpack entropy table indices and predictor for current CB1 index */
     silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );
 
-    /* Trellis dequantizer */
+    /* Predictive residual dequantizer */
     silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
 
     /* Weights from codebook vector */
--- a/silk/NLSF_unpack.c
+++ b/silk/NLSF_unpack.c
@@ -33,7 +33,7 @@
 
 /* Unpack predictor values and indices for entropy coding tables */
 void silk_NLSF_unpack(
-          opus_int16            ec_ix[],                        /* O    Indices to entropy tales [ LPC_ORDER ]      */
+          opus_int16            ec_ix[],                        /* O    Indices to entropy tables [ LPC_ORDER ]     */
           opus_uint8            pred_Q8[],                      /* O    LSF predictor [ LPC_ORDER ]                 */
     const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */
     const opus_int              CB1_index                       /* I    Index of vector in first LSF codebook       */
--- a/silk/NSQ.c
+++ b/silk/NSQ.c
@@ -190,7 +190,7 @@
     opus_int     i, j;
     opus_int32   LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
     opus_int32   n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
-    opus_int32   dither, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
+    opus_int32   exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
     opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;
     opus_int32   *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
 
@@ -205,9 +205,6 @@
         /* Generate dither */
         NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
 
-        /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
-        dither = silk_RSHIFT( NSQ->rand_seed, 31 );
-
         /* Short-term prediction */
         silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
         /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
@@ -292,7 +289,9 @@
         r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 );                              /* residual error Q10 */
 
         /* Flip sign depending on dither */
-        r_Q10 = r_Q10 ^ dither;
+        if ( NSQ->rand_seed < 0 ) {
+           r_Q10 = -r_Q10;
+        }
         r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
 
         /* Find two quantization level candidates and measure their rate-distortion */
@@ -333,7 +332,10 @@
         pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
 
         /* Excitation */
-        exc_Q14 = silk_LSHIFT( q1_Q10, 4 ) ^ dither;
+        exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
+        if ( NSQ->rand_seed < 0 ) {
+           exc_Q14 = -exc_Q14;
+        }
 
         /* Add predictions */
         LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
--- a/silk/NSQ_del_dec.c
+++ b/silk/NSQ_del_dec.c
@@ -325,7 +325,7 @@
     opus_int32   Winner_rand_state;
     opus_int32   LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
     opus_int32   n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
-    opus_int32   q1_Q0, q1_Q10, q2_Q10, dither, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
+    opus_int32   q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
     opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;
     opus_int32   *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
     NSQ_sample_struct  psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
@@ -378,9 +378,6 @@
             /* Generate dither */
             psDD->Seed = silk_RAND( psDD->Seed );
 
-            /* dither = rand_seed < 0 ? 0xFFFFFFFF : 0; */
-            dither = silk_RSHIFT( psDD->Seed, 31 );
-
             /* Pointer used in short term prediction and shaping */
             psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
             /* Short-term prediction */
@@ -448,7 +445,9 @@
             r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 );                                     /* residual error Q10 */
 
             /* Flip sign depending on dither */
-            r_Q10 = r_Q10 ^ dither;
+            if ( psDD->Seed < 0 ) {
+                r_Q10 = -r_Q10;
+            }
             r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
 
             /* Find two quantization level candidates and measure their rate-distortion */
@@ -497,7 +496,10 @@
             /* Update states for best quantization */
 
             /* Quantized excitation */
-            exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ) ^ dither;
+            exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
+            if ( psDD->Seed < 0 ) {
+                exc_Q14 = -exc_Q14;
+            }
 
             /* Add predictions */
             LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
@@ -513,7 +515,11 @@
             /* Update states for second best quantization */
 
             /* Quantized excitation */
-            exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ) ^ dither;
+            exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
+            if ( psDD->Seed < 0 ) {
+                exc_Q14 = -exc_Q14;
+            }
+
 
             /* Add predictions */
             LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
--- a/silk/decode_core.c
+++ b/silk/decode_core.c
@@ -72,8 +72,9 @@
             psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4;
         }
         psDec->exc_Q14[ i ] += offset_Q10 << 4;
-        if ( rand_seed < 0 )
+        if( rand_seed < 0 ) {
            psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ];
+        }
 
         rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] );
     }
--- a/silk/define.h
+++ b/silk/define.h
@@ -130,7 +130,7 @@
 #define QUANT_LEVEL_ADJUST_Q10                  80
 
 /* Maximum numbers of iterations used to stabilize an LPC vector */
-#define MAX_LPC_STABILIZE_ITERATIONS            15
+#define MAX_LPC_STABILIZE_ITERATIONS            16
 #define MAX_PREDICTION_POWER_GAIN               1e4f
 #define MAX_PREDICTION_POWER_GAIN_AFTER_RESET   1e2f
 
--- a/silk/main.h
+++ b/silk/main.h
@@ -331,7 +331,7 @@
 
 /* Unpack predictor values and indices for entropy coding tables */
 void silk_NLSF_unpack(
-          opus_int16            ec_ix[],                        /* O    Indices to entropy tales [ LPC_ORDER ]      */
+          opus_int16            ec_ix[],                        /* O    Indices to entropy tables [ LPC_ORDER ]     */
           opus_uint8            pred_Q8[],                      /* O    LSF predictor [ LPC_ORDER ]                 */
     const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */
     const opus_int              CB1_index                       /* I    Index of vector in first LSF codebook       */