shithub: opus

Download patch

ref: a0bd7d3b8420be9c96f4e65e6113e11a05a23717
parent: 184a4767aad0e813cffa4aa178e0c161a4d17253
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Fri Jul 22 05:13:00 EDT 2016

fixes overflows in celt_iir() by doing proper saturation

--- a/celt/arch.h
+++ b/celt/arch.h
@@ -206,6 +206,7 @@
 #define SATURATE16(x)   (x)
 
 #define ROUND16(a,shift)  (a)
+#define SROUND16(a,shift) (a)
 #define HALF16(x)       (.5f*(x))
 #define HALF32(x)       (.5f*(x))
 
--- a/celt/celt_lpc.c
+++ b/celt/celt_lpc.c
@@ -166,7 +166,7 @@
       {
          mem[j]=mem[j-1];
       }
-      mem[0] = ROUND16(sum,SIG_SHIFT);
+      mem[0] = SROUND16(sum, SIG_SHIFT);
       _y[i] = sum;
    }
 #else
@@ -195,20 +195,20 @@
       xcorr_kernel(rden, y+i, sum, ord, arch);
 
       /* Patch up the result to compensate for the fact that this is an IIR */
-      y[i+ord  ] = -ROUND16(sum[0],SIG_SHIFT);
+      y[i+ord  ] = -SROUND16(sum[0],SIG_SHIFT);
       _y[i  ] = sum[0];
       sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);
-      y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);
+      y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
       _y[i+1] = sum[1];
       sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
       sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);
-      y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);
+      y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
       _y[i+2] = sum[2];
 
       sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
       sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
       sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);
-      y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);
+      y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
       _y[i+3] = sum[3];
    }
    for (;i<N;i++)
@@ -216,7 +216,7 @@
       opus_val32 sum = _x[i];
       for (j=0;j<ord;j++)
          sum -= MULT16_16(rden[j],y[i+j]);
-      y[i+ord] = ROUND16(sum,SIG_SHIFT);
+      y[i+ord] = SROUND16(sum,SIG_SHIFT);
       _y[i] = sum;
    }
    for(i=0;i<ord;i++)
--- a/celt/fixed_debug.h
+++ b/celt/fixed_debug.h
@@ -233,6 +233,8 @@
 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
 
 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
+#define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
+
 #define HALF16(x)  (SHR16(x,1))
 #define HALF32(x)  (SHR32(x,1))
 
--- a/celt/fixed_generic.h
+++ b/celt/fixed_generic.h
@@ -104,6 +104,9 @@
 
 /** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
 #define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
+/** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */
+#define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767));
+
 /** Divide by two */
 #define HALF16(x)  (SHR16(x,1))
 #define HALF32(x)  (SHR32(x,1))