shithub: opus

Download patch

ref: e2f1aac572994feaf6162df2c39ef755c00831fd
parent: 4f1b7dac7e3b1ed0c9acce9c208c8c972f3d95d4
author: Koen Vos <[email protected]>
date: Wed Oct 12 17:30:58 EDT 2011

Fixes a corner case that was causing silk_A2NLSF() to fail

Input that caused the problem was:
a_Q16[] = [129763 -49346 -42032 5488 28014 -1549 -2384 -8568
3154 -5104 -1605 6291 11861 -1843 -17715 7361]

--- a/silk/A2NLSF.c
+++ b/silk/A2NLSF.c
@@ -129,7 +129,7 @@
 {
     opus_int      i, k, m, dd, root_ix, ffrac;
     opus_int32 xlo, xhi, xmid;
-    opus_int32 ylo, yhi, ymid;
+    opus_int32 ylo, yhi, ymid, thr;
     opus_int32 nom, den;
     opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ];
     opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
@@ -161,6 +161,7 @@
     }
     k = 1;                          /* Loop counter */
     i = 0;                          /* Counter for bandwidth expansions applied */
+    thr = 0;
     while( 1 ) {
         /* Evaluate polynomial */
 #if OVERSAMPLE_COSINE_TABLE
@@ -173,7 +174,14 @@
         yhi = silk_A2NLSF_eval_poly( p, xhi, dd );
 
         /* Detect zero crossing */
-        if( ( ylo <= 0 && yhi >= 0 ) || ( ylo >= 0 && yhi <= 0 ) ) {
+        if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) {
+            if( yhi == 0 ) {
+                /* If the root lies exactly at the end of the current       */
+                /* interval, look for the next root in the next interval    */
+                thr = 1;
+            } else {
+                thr = 0;
+            }
             /* Binary division */
 #if OVERSAMPLE_COSINE_TABLE
             ffrac = -128;
@@ -220,8 +228,7 @@
             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 );
-            silk_assert( NLSF[ root_ix ] <= 32767 );
+            silk_assert( NLSF[ root_ix ] >= 0 );
 
             root_ix++;        /* Next root */
             if( root_ix >= d ) {
@@ -243,8 +250,9 @@
         } else {
             /* Increment loop counter */
             k++;
-            xlo    = xhi;
-            ylo    = yhi;
+            xlo = xhi;
+            ylo = yhi;
+            thr = 0;
 
 #if OVERSAMPLE_COSINE_TABLE
             if( k > 2 * LSF_COS_TAB_SZ_FIX ) {