Renamed SKP_[u]int* to opus_[u]int*
[opus.git] / silk / silk_NLSF2A.c
index 21251cf..da9cfa8 100644 (file)
@@ -34,23 +34,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "silk_SigProc_FIX.h"\r
 #include "silk_tables.h"\r
 \r
+#define QA      16\r
+\r
 /* helper function for NLSF2A(..) */\r
 SKP_INLINE void silk_NLSF2A_find_poly(\r
-    SKP_int32          *out,      /* o    intermediate polynomial, Q20            */\r
-    const SKP_int32    *cLSF,     /* i    vector of interleaved 2*cos(LSFs), Q20  */\r
-    SKP_int            dd         /* i    polynomial order (= 1/2 * filter order) */\r
+    opus_int32          *out,      /* O    intermediate polynomial, QA [dd+1]        */\r
+    const opus_int32    *cLSF,     /* I    vector of interleaved 2*cos(LSFs), QA [d] */\r
+    opus_int            dd         /* I    polynomial order (= 1/2 * filter order)   */\r
 )\r
 {\r
-    SKP_int        k, n;\r
-    SKP_int32    ftmp;\r
+    opus_int   k, n;\r
+    opus_int32 ftmp;\r
 \r
-    out[0] = SKP_LSHIFT( 1, 20 );\r
+    out[0] = SKP_LSHIFT( 1, QA );\r
     out[1] = -cLSF[0];\r
     for( k = 1; k < dd; k++ ) {\r
-        ftmp = cLSF[2*k];            // Q20\r
-        out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), 20 );\r
+        ftmp = cLSF[2*k];            // QA\r
+        out[k+1] = SKP_LSHIFT( out[k-1], 1 ) - (opus_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[k] ), QA );\r
         for( n = k; n > 1; n-- ) {\r
-            out[n] += out[n-2] - (SKP_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), 20 );\r
+            out[n] += out[n-2] - (opus_int32)SKP_RSHIFT_ROUND64( SKP_SMULL( ftmp, out[n-1] ), QA );\r
         }\r
         out[1] -= ftmp;\r
     }\r
@@ -58,24 +60,21 @@ SKP_INLINE void silk_NLSF2A_find_poly(
 \r
 /* compute whitening filter coefficients from normalized line spectral frequencies */\r
 void silk_NLSF2A(\r
-    SKP_int16        *a,              /* o    monic whitening filter coefficients in Q12,  [d]    */\r
-    const SKP_int16  *NLSF,           /* i    normalized line spectral frequencies in Q15, [d]    */\r
-    const SKP_int    d                /* i    filter order (should be even)                       */\r
+    opus_int16        *a_Q12,            /* O    monic whitening filter coefficients in Q12,  [ d ]  */\r
+    const opus_int16  *NLSF,             /* I    normalized line spectral frequencies in Q15, [ d ]  */\r
+    const opus_int    d                  /* I    filter order (should be even)                       */\r
 )\r
 {\r
-    SKP_int k, i, dd;\r
-    SKP_int32 cos_LSF_Q20[SILK_MAX_ORDER_LPC];\r
-    SKP_int32 P[SILK_MAX_ORDER_LPC/2+1], Q[SILK_MAX_ORDER_LPC/2+1];\r
-    SKP_int32 Ptmp, Qtmp;\r
-    SKP_int32 f_int;\r
-    SKP_int32 f_frac;\r
-    SKP_int32 cos_val, delta;\r
-    SKP_int32 a_int32[SILK_MAX_ORDER_LPC];\r
-    SKP_int32 maxabs, absval, idx=0, sc_Q16; \r
+    opus_int   k, i, dd;\r
+    opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ];\r
+    opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];\r
+    opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;\r
+    opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];\r
+    opus_int32 maxabs, absval, idx=0, sc_Q16, invGain_Q30; \r
 \r
     SKP_assert( LSF_COS_TAB_SZ_FIX == 128 );\r
 \r
-    /* convert LSFs to 2*cos(LSF(i)), using piecewise linear curve from table */\r
+    /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */\r
     for( k = 0; k < d; k++ ) {\r
         SKP_assert(NLSF[k] >= 0 );\r
         SKP_assert(NLSF[k] <= 32767 );\r
@@ -94,59 +93,79 @@ void silk_NLSF2A(
         delta   = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val;  /* Q12, with a range of 0..200 */\r
 \r
         /* Linear interpolation */\r
-        cos_LSF_Q20[k] = SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ); /* Q20 */\r
+        cos_LSF_QA[k] = SKP_RSHIFT_ROUND( SKP_LSHIFT( cos_val, 8 ) + SKP_MUL( delta, f_frac ), 20 - QA ); /* QA */\r
     }\r
     \r
     dd = SKP_RSHIFT( d, 1 );\r
 \r
     /* generate even and odd polynomials using convolution */\r
-    silk_NLSF2A_find_poly( P, &cos_LSF_Q20[0], dd );\r
-    silk_NLSF2A_find_poly( Q, &cos_LSF_Q20[1], dd );\r
+    silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd );\r
+    silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd );\r
 \r
-    /* convert even and odd polynomials to SKP_int32 Q12 filter coefs */\r
+    /* convert even and odd polynomials to opus_int32 Q12 filter coefs */\r
     for( k = 0; k < dd; k++ ) {\r
-        Ptmp = P[k+1] + P[k];\r
-        Qtmp = Q[k+1] - Q[k];\r
+        Ptmp = P[ k+1 ] + P[ k ];\r
+        Qtmp = Q[ k+1 ] - Q[ k ];\r
 \r
         /* the Ptmp and Qtmp values at this stage need to fit in int32 */\r
-\r
-        a_int32[k]     = -SKP_RSHIFT_ROUND( Ptmp + Qtmp, 9 ); /* Q20 -> Q12 */\r
-        a_int32[d-k-1] =  SKP_RSHIFT_ROUND( Qtmp - Ptmp, 9 ); /* Q20 -> Q12 */\r
+        a32_QA1[ k ]     = -Qtmp - Ptmp;        /* QA+1 */\r
+        a32_QA1[ d-k-1 ] =  Qtmp - Ptmp;        /* QA+1 */\r
     }\r
 \r
-    /* Limit the maximum absolute value of the prediction coefficients */\r
+    /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */\r
     for( i = 0; i < 10; i++ ) {\r
         /* Find maximum absolute value and its index */\r
         maxabs = 0;\r
         for( k = 0; k < d; k++ ) {\r
-            absval = SKP_abs( a_int32[k] );\r
+            absval = SKP_abs( a32_QA1[k] );\r
             if( absval > maxabs ) {\r
                 maxabs = absval;\r
-                idx       = k;\r
+                idx    = k;\r
             }    \r
         }\r
+        maxabs = SKP_RSHIFT_ROUND( maxabs, QA + 1 - 12 );       /* QA+1 -> Q12 */\r
     \r
         if( maxabs > SKP_int16_MAX ) {    \r
             /* Reduce magnitude of prediction coefficients */\r
-            maxabs = SKP_min( maxabs, 98369 ); // ( SKP_int32_MAX / ( 65470 >> 2 ) ) + SKP_int16_MAX = 98369 \r
-            sc_Q16 = 65470 - SKP_DIV32( SKP_MUL( 65470 >> 2, maxabs - SKP_int16_MAX ), \r
+            maxabs = SKP_min( maxabs, 163838 );  /* ( SKP_int32_MAX >> 14 ) + SKP_int16_MAX = 163838 */\r
+            sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - SKP_DIV32( SKP_LSHIFT( maxabs - SKP_int16_MAX, 14 ), \r
                                         SKP_RSHIFT32( SKP_MUL( maxabs, idx + 1), 2 ) );\r
-            silk_bwexpander_32( a_int32, d, sc_Q16 );\r
+            silk_bwexpander_32( a32_QA1, d, sc_Q16 );\r
         } else {\r
             break;\r
         }\r
     }    \r
 \r
-    /* Reached the last iteration */\r
     if( i == 10 ) {\r
-        SKP_assert(0);\r
+        /* Reached the last iteration, clip the coefficients */\r
+        for( k = 0; k < d; k++ ) {\r
+            a_Q12[ k ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */\r
+            a32_QA1[ k ] = SKP_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );\r
+        }\r
+    } else {\r
         for( k = 0; k < d; k++ ) {\r
-            a_int32[k] = SKP_SAT16( a_int32[k] ); \r
+            a_Q12[ k ] = (opus_int16)SKP_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );       /* QA+1 -> Q12 */\r
         }\r
     }\r
 \r
-    /* Return as SKP_int16 Q12 coefficients */\r
-    for( k = 0; k < d; k++ ) {\r
-        a[k] = (SKP_int16)a_int32[k];\r
+    for( i = 1; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {\r
+        if( silk_LPC_inverse_pred_gain( &invGain_Q30, a_Q12, d ) == 1 ) {\r
+            /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion   */\r
+            /* on the unscaled coefficients, convert to Q12 and measure again                   */\r
+            silk_bwexpander_32( a32_QA1, d, 65536 - SKP_SMULBB( 9 + i, i ) );              /* 10_Q16 = 0.00015 */\r
+            for( k = 0; k < d; k++ ) {\r
+                a_Q12[ k ] = (opus_int16)SKP_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );  /* QA+1 -> Q12 */\r
+            }\r
+        } else {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if( i == MAX_LPC_STABILIZE_ITERATIONS ) {\r
+        /* Reached the last iteration, set coefficients to zero */\r
+        for( k = 0; k < d; k++ ) {\r
+            a_Q12[ k ] = 0;\r
+        }\r
     }\r
 }\r
+\r