Update SILK code using the CELT range coder
[opus.git] / src_SigProc_FIX / SKP_Silk_LPC_inv_pred_gain.c
similarity index 69%
rename from src/SKP_Silk_LPC_inv_pred_gain.c
rename to src_SigProc_FIX/SKP_Silk_LPC_inv_pred_gain.c
index a350a6f..c4f0e20 100644 (file)
@@ -31,30 +31,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * Compute inverse of LPC prediction gain, and                          *\r
  * test if LPC coefficients are stable (all poles within unit circle)   *\r
  *                                                                      *\r
- * Copyright 2008 (c), Skype Limited                                           *\r
+ * Copyright 2008 (c), Skype Limited                                    *\r
  *                                                                      */\r
 #include "SKP_Silk_SigProc_FIX.h"\r
 #define QA          16\r
-#define A_LIMIT     65520\r
+#define A_LIMIT     SKP_FIX_CONST( 0.99975, QA )\r
 \r
 /* Compute inverse of LPC prediction gain, and                          */\r
 /* test if LPC coefficients are stable (all poles within unit circle)   */\r
-SKP_int SKP_Silk_LPC_inverse_pred_gain(       /* O:   Returns 1 if unstable, otherwise 0          */\r
+static SKP_int LPC_inverse_pred_gain_QA(        /* O:   Returns 1 if unstable, otherwise 0          */\r
     SKP_int32           *invGain_Q30,           /* O:   Inverse prediction gain, Q30 energy domain  */\r
-    const SKP_int16     *A_Q12,                 /* I:   Prediction coefficients, Q12 [order]        */\r
+    SKP_int32           A_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ],         \r
+                                                /* I:   Prediction coefficients                     */\r
     const SKP_int       order                   /* I:   Prediction order                            */\r
 )\r
 {\r
     SKP_int   k, n, headrm;\r
-    SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16;\r
-    SKP_int32 Atmp_QA[ 2 ][ SigProc_MAX_ORDER_LPC ], tmp_QA;\r
+    SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16, tmp_QA;\r
     SKP_int32 *Aold_QA, *Anew_QA;\r
 \r
-    Anew_QA = Atmp_QA[ order & 1 ];\r
-    /* Increase Q domain of the AR coefficients */\r
-    for( k = 0; k < order; k++ ) {\r
-        Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 );\r
-    }\r
+    Anew_QA = A_QA[ order & 1 ];\r
 \r
     *invGain_Q30 = ( 1 << 30 );\r
     for( k = order - 1; k > 0; k-- ) {\r
@@ -82,7 +78,7 @@ SKP_int SKP_Silk_LPC_inverse_pred_gain(       /* O:   Returns 1 if unstable, oth
 \r
         /* Swap pointers */\r
         Aold_QA = Anew_QA;\r
-        Anew_QA = Atmp_QA[ k & 1 ];\r
+        Anew_QA = A_QA[ k & 1 ];\r
         \r
         /* Update AR coefficient */\r
         headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;\r
@@ -113,77 +109,65 @@ SKP_int SKP_Silk_LPC_inverse_pred_gain(       /* O:   Returns 1 if unstable, oth
     return 0;\r
 }\r
 \r
-/* For input in Q13 domain */\r
-SKP_int SKP_Silk_LPC_inverse_pred_gain_Q13(   /* O:   Returns 1 if unstable, otherwise 0          */\r
+/* For input in Q12 domain */\r
+SKP_int SKP_Silk_LPC_inverse_pred_gain(       /* O:   Returns 1 if unstable, otherwise 0          */\r
     SKP_int32           *invGain_Q30,           /* O:   Inverse prediction gain, Q30 energy domain  */\r
-    const SKP_int16     *A_Q13,                 /* I:   Prediction coefficients, Q13 [order]        */\r
+    const SKP_int16     *A_Q12,                 /* I:   Prediction coefficients, Q12 [order]        */\r
     const SKP_int       order                   /* I:   Prediction order                            */\r
 )\r
 {\r
-    SKP_int   k, n, headrm;\r
-    SKP_int32 rc_Q31, rc_mult1_Q30, rc_mult2_Q16;\r
-    SKP_int32 Atmp_QA[ 2 ][ SigProc_MAX_ORDER_LPC ], tmp_QA;\r
-    SKP_int32 *Aold_QA, *Anew_QA;\r
+    SKP_int   k;\r
+    SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];\r
+    SKP_int32 *Anew_QA;\r
 \r
     Anew_QA = Atmp_QA[ order & 1 ];\r
+\r
     /* Increase Q domain of the AR coefficients */\r
     for( k = 0; k < order; k++ ) {\r
-        Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q13[ k ], QA - 13 );\r
+        Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q12[ k ], QA - 12 );\r
     }\r
 \r
-    *invGain_Q30 = ( 1 << 30 );\r
-    for( k = order - 1; k > 0; k-- ) {\r
-        /* Check for stability */\r
-        if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {\r
-            return 1;\r
-        }\r
-\r
-        /* Set RC equal to negated AR coef */\r
-        rc_Q31 = -SKP_LSHIFT( Anew_QA[ k ], 31 - QA );\r
-        \r
-        /* rc_mult1_Q30 range: [ 1 : 2^30-1 ] */\r
-        rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );\r
-        SKP_assert( rc_mult1_Q30 > ( 1 << 15 ) );                   /* reduce A_LIMIT if fails */\r
-        SKP_assert( rc_mult1_Q30 < ( 1 << 30 ) );\r
+    return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );\r
+}\r
 \r
-        /* rc_mult2_Q16 range: [ 2^16 : SKP_int32_MAX ] */\r
-        rc_mult2_Q16 = SKP_INVERSE32_varQ( rc_mult1_Q30, 46 );      /* 16 = 46 - 30 */\r
+/* For input in Q13 domain */\r
+SKP_int SKP_Silk_LPC_inverse_pred_gain_Q13(   /* O:   Returns 1 if unstable, otherwise 0          */\r
+    SKP_int32           *invGain_Q30,           /* O:   Inverse prediction gain, Q30 energy domain  */\r
+    const SKP_int16     *A_Q13,                 /* I:   Prediction coefficients, Q13 [order]        */\r
+    const SKP_int       order                   /* I:   Prediction order                            */\r
+)\r
+{\r
+    SKP_int   k;\r
+    SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];\r
+    SKP_int32 *Anew_QA;\r
 \r
-        /* Update inverse gain */\r
-        /* invGain_Q30 range: [ 0 : 2^30 ] */\r
-        *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );\r
-        SKP_assert( *invGain_Q30 >= 0     );\r
-        SKP_assert( *invGain_Q30 <= 1<<30 );\r
+    Anew_QA = Atmp_QA[ order & 1 ];\r
 \r
-        /* Swap pointers */\r
-        Aold_QA = Anew_QA;\r
-        Anew_QA = Atmp_QA[ k & 1 ];\r
-        \r
-        /* Update AR coefficient */\r
-        headrm = SKP_Silk_CLZ32( rc_mult2_Q16 ) - 1;\r
-        rc_mult2_Q16 = SKP_LSHIFT( rc_mult2_Q16, headrm );          /* Q: 16 + headrm */\r
-        for( n = 0; n < k; n++ ) {\r
-            tmp_QA = Aold_QA[ n ] - SKP_LSHIFT( SKP_SMMUL( Aold_QA[ k - n - 1 ], rc_Q31 ), 1 );\r
-            Anew_QA[ n ] = SKP_LSHIFT( SKP_SMMUL( tmp_QA, rc_mult2_Q16 ), 16 - headrm );\r
-        }\r
+    /* Increase Q domain of the AR coefficients */\r
+    for( k = 0; k < order; k++ ) {\r
+        Anew_QA[ k ] = SKP_LSHIFT( (SKP_int32)A_Q13[ k ], QA - 13 );\r
     }\r
 \r
-    /* Check for stability */\r
-    if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {\r
-        return 1;\r
-    }\r
+    return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );\r
+}\r
 \r
-    /* Set RC equal to negated AR coef */\r
-    rc_Q31 = -SKP_LSHIFT( Anew_QA[ 0 ], 31 - QA );\r
+/* For input in Q24 domain */\r
+SKP_int SKP_Silk_LPC_inverse_pred_gain_Q24(   /* O:   Returns 1 if unstable, otherwise 0          */\r
+    SKP_int32           *invGain_Q30,           /* O:   Inverse prediction gain, Q30 energy domain  */\r
+    const SKP_int32     *A_Q24,                 /* I:   Prediction coefficients, Q24 [order]        */\r
+    const SKP_int       order                   /* I:   Prediction order                            */\r
+)\r
+{\r
+    SKP_int   k;\r
+    SKP_int32 Atmp_QA[ 2 ][ SKP_Silk_MAX_ORDER_LPC ];\r
+    SKP_int32 *Anew_QA;\r
 \r
-    /* Range: [ 1 : 2^30 ] */\r
-    rc_mult1_Q30 = ( SKP_int32_MAX >> 1 ) - SKP_SMMUL( rc_Q31, rc_Q31 );\r
+    Anew_QA = Atmp_QA[ order & 1 ];\r
 \r
-    /* Update inverse gain */\r
-    /* Range: [ 0 : 2^30 ] */\r
-    *invGain_Q30 = SKP_LSHIFT( SKP_SMMUL( *invGain_Q30, rc_mult1_Q30 ), 2 );\r
-    SKP_assert( *invGain_Q30 >= 0     );\r
-    SKP_assert( *invGain_Q30 <= 1<<30 );\r
+    /* Increase Q domain of the AR coefficients */\r
+    for( k = 0; k < order; k++ ) {\r
+        Anew_QA[ k ] = SKP_RSHIFT_ROUND( A_Q24[ k ], 24 - QA );\r
+    }\r
 \r
-    return 0;\r
+    return LPC_inverse_pred_gain_QA( invGain_Q30, Atmp_QA, order );\r
 }\r