Move misplaced RESTORE_STACK.
[opus.git] / silk / A2NLSF.c
index 2881e8d..58adf7b 100644 (file)
@@ -1,28 +1,28 @@
 /***********************************************************************
 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
 Redistribution and use in source and binary forms, with or without
-modification, (subject to the limitations in the disclaimer below)
-are permitted provided that the following conditions are met:
+modification, are permitted provided that the following conditions
+are met:
 - Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 - Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in the
 documentation and/or other materials provided with the distribution.
-- Neither the name of Skype Limited, nor the names of specific
-contributors, may be used to endorse or promote products derived from
-this software without specific prior written permission.
-NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
-BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the 
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
 ***********************************************************************/
 
 /* Conversion between prediction filter coefficients and NLSFs  */
@@ -40,17 +40,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /* 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
 
-/* Flag for using 2x as many cosine sampling points, reduces the risk of missing a root */
-#define OVERSAMPLE_COSINE_TABLE       0
-
 /* Helper function for A2NLSF(..)                    */
 /* Transforms polynomials from cos(n*f) to cos(f)^n  */
 static inline void silk_A2NLSF_trans_poly(
-    opus_int32        *p,    /* I/O    Polynomial                                */
-    const opus_int    dd     /* I      Polynomial order (= filter order / 2 )    */
+    opus_int32          *p,                     /* I/O    Polynomial                                */
+    const opus_int      dd                      /* I      Polynomial order (= filter order / 2 )    */
 )
 {
     opus_int k, n;
@@ -62,21 +58,21 @@ static inline void silk_A2NLSF_trans_poly(
         p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 );
     }
 }
-/* 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        */
-    const opus_int32   x,    /* I    Evaluation point, Q12    */
-    const opus_int    dd     /* I    Order                    */
+/* Helper function for A2NLSF(..) */
+/* Polynomial evaluation          */
+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                                   */
 )
 {
     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;
 }
@@ -91,19 +87,11 @@ static inline void silk_A2NLSF_init(
     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, */
@@ -119,12 +107,12 @@ static inline void silk_A2NLSF_init(
     silk_A2NLSF_trans_poly( Q, dd );
 }
 
-/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients        */
-/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence.    */
+/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients      */
+/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
 void silk_A2NLSF(
-    opus_int16        *NLSF,                 /* O    Normalized Line Spectral Frequencies, Q15 (0 - (2^15-1)), [d]    */
-    opus_int32        *a_Q16,                /* I/O  Monic whitening filter coefficients in Q16 [d]                   */
-    const opus_int    d                      /* I    Filter order (must be even)                                      */
+    opus_int16                  *NLSF,              /* O    Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */
+    opus_int32                  *a_Q16,             /* I/O  Monic whitening filter coefficients in Q16 [d]              */
+    const opus_int              d                   /* I    Filter order (must be even)                                 */
 )
 {
     opus_int      i, k, m, dd, root_ix, ffrac;
@@ -145,7 +133,7 @@ void silk_A2NLSF(
     silk_A2NLSF_init( a_Q16, P, Q, dd );
 
     /* Find roots, alternating between P and Q */
-    p = P;    /* Pointer to polynomial */
+    p = P;                          /* Pointer to polynomial */
 
     xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
     ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
@@ -164,13 +152,7 @@ void silk_A2NLSF(
     thr = 0;
     while( 1 ) {
         /* Evaluate polynomial */
-#if OVERSAMPLE_COSINE_TABLE
-        xhi = silk_LSFCosTab_FIX_Q12[   k       >> 1 ] +
-          ( ( silk_LSFCosTab_FIX_Q12[ ( k + 1 ) >> 1 ] -
-              silk_LSFCosTab_FIX_Q12[   k       >> 1 ] ) >> 1 );    /* Q12 */
-#else
         xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
-#endif
         yhi = silk_A2NLSF_eval_poly( p, xhi, dd );
 
         /* Detect zero crossing */
@@ -183,11 +165,7 @@ void silk_A2NLSF(
                 thr = 0;
             }
             /* Binary division */
-#if OVERSAMPLE_COSINE_TABLE
-            ffrac = -128;
-#else
             ffrac = -256;
-#endif
             for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
                 /* Evaluate polynomial */
                 xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 );
@@ -202,11 +180,7 @@ void silk_A2NLSF(
                     /* Increase frequency */
                     xlo = xmid;
                     ylo = ymid;
-#if OVERSAMPLE_COSINE_TABLE
-                    ffrac = silk_ADD_RSHIFT( ffrac,  64, m );
-#else
                     ffrac = silk_ADD_RSHIFT( ffrac, 128, m );
-#endif
                 }
             }
 
@@ -222,11 +196,7 @@ void silk_A2NLSF(
                 /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
                 ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
             }
-#if OVERSAMPLE_COSINE_TABLE
-            NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 7 ) + ffrac, silk_int16_MAX );
-#else
             NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX );
-#endif
 
             silk_assert( NLSF[ root_ix ] >= 0 );
 
@@ -239,13 +209,7 @@ void silk_A2NLSF(
             p = PQ[ root_ix & 1 ];
 
             /* Evaluate polynomial */
-#if OVERSAMPLE_COSINE_TABLE
-            xlo = silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] +
-              ( ( silk_LSFCosTab_FIX_Q12[   k       >> 1 ] -
-                  silk_LSFCosTab_FIX_Q12[ ( k - 1 ) >> 1 ] ) >> 1 ); /* Q12*/
-#else
             xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/
-#endif
             ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 );
         } else {
             /* Increment loop counter */
@@ -254,11 +218,7 @@ void silk_A2NLSF(
             ylo = yhi;
             thr = 0;
 
-#if OVERSAMPLE_COSINE_TABLE
-            if( k > 2 * LSF_COS_TAB_SZ_FIX ) {
-#else
             if( k > LSF_COS_TAB_SZ_FIX ) {
-#endif
                 i++;
                 if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
                     /* Set NLSFs to white spectrum and exit */