Optimizes _celt_autocorr() by using pitch_xcorr()
[opus.git] / celt / celt_lpc.c
index 7842030..8c6cfec 100644 (file)
@@ -15,8 +15,8 @@
    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 FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   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
@@ -32,6 +32,7 @@
 #include "celt_lpc.h"
 #include "stack_alloc.h"
 #include "mathops.h"
+#include "pitch.h"
 
 void _celt_lpc(
       opus_val16       *_lpc, /* out: [0...p-1] LPC coefficients      */
@@ -101,7 +102,7 @@ void celt_fir(const opus_val16 *x,
       opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
       for (j=0;j<ord;j++)
       {
-         sum += MULT16_16(num[j],mem[j]);
+         sum = MAC16_16(sum,num[j],mem[j]);
       }
       for (j=ord-1;j>=1;j--)
       {
@@ -147,6 +148,7 @@ void _celt_autocorr(
 {
    opus_val32 d;
    int i;
+   int fastN=n-lag;
    VARDECL(opus_val16, xx);
    SAVE_STACK;
    ALLOC(xx, n, opus_val16);
@@ -161,23 +163,28 @@ void _celt_autocorr(
    }
 #ifdef FIXED_POINT
    {
-      opus_val32 ac0=0;
+      opus_val32 ac0;
       int shift;
-      for(i=0;i<n;i++)
-         ac0 += SHR32(MULT16_16(xx[i],xx[i]),8);
-      ac0 += 1+n;
+      ac0 = 1+n;
+      if (n&1) ac0 += SHR32(MULT16_16(xx[0],xx[0]),9);
+      for(i=(n&1);i<n;i+=2)
+      {
+         ac0 += SHR32(MULT16_16(xx[i],xx[i]),9);
+         ac0 += SHR32(MULT16_16(xx[i+1],xx[i+1]),9);
+      }
 
-      shift = celt_ilog2(ac0)-30+9;
+      shift = celt_ilog2(ac0)-30+10;
       shift = (shift+1)/2;
       for(i=0;i<n;i++)
          xx[i] = VSHR32(xx[i], shift);
    }
 #endif
+   pitch_xcorr(xx, xx, ac, fastN, lag+1);
    while (lag>=0)
    {
-      for (i = lag, d = 0; i < n; i++)
-         d += xx[i] * xx[i-lag];
-      ac[lag] = d;
+      for (i = lag+fastN, d = 0; i < n; i++)
+         d = MAC16_16(d, xx[i], xx[i-lag]);
+      ac[lag] += d;
       /*printf ("%f ", ac[lag]);*/
       lag--;
    }