Adds a fuzzing mode that causes the encoder to make random decisions
[opus.git] / libcelt / pitch.c
index bff5c70..89a00f8 100644 (file)
    Redistribution and use in source and binary forms, with or without
    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 the Xiph.org Foundation nor the names of its
-   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
@@ -35,7 +31,6 @@
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 #include "stack_alloc.h"
 #include "mathops.h"
 
-static void find_best_pitch(celt_word32 *xcorr, celt_word32 maxcorr, celt_word16 *y,
-                            int yshift, int len, int max_pitch, int best_pitch[2])
+static void find_best_pitch(opus_val32 *xcorr, opus_val32 maxcorr, opus_val16 *y,
+                            int yshift, int len, int max_pitch, int *best_pitch)
 {
    int i, j;
-   celt_word32 Syy=1;
-   celt_word16 best_num[2];
-   celt_word32 best_den[2];
+   opus_val32 Syy=1;
+   opus_val16 best_num[2];
+   opus_val32 best_den[2];
 #ifdef FIXED_POINT
    int xshift;
 
@@ -71,8 +66,8 @@ static void find_best_pitch(celt_word32 *xcorr, celt_word32 maxcorr, celt_word16
    {
       if (xcorr[i]>0)
       {
-         celt_word16 num;
-         celt_word32 xcorr16;
+         opus_val16 num;
+         opus_val32 xcorr16;
          xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift));
          num = MULT16_16_Q15(xcorr16,xcorr16);
          if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))
@@ -98,23 +93,22 @@ static void find_best_pitch(celt_word32 *xcorr, celt_word32 maxcorr, celt_word16
 }
 
 #include "plc.h"
-void pitch_downsample(celt_sig * restrict x[], celt_word16 * restrict x_lp, int len, int end, int _C, celt_sig * restrict xmem, celt_word16 * restrict filt_mem)
+void pitch_downsample(celt_sig * restrict x[], opus_val16 * restrict x_lp,
+      int len, int _C)
 {
    int i;
-   celt_word32 ac[5];
-   celt_word16 tmp=Q15ONE;
-   celt_word16 lpc[4], mem[4]={0,0,0,0};
+   opus_val32 ac[5];
+   opus_val16 tmp=Q15ONE;
+   opus_val16 lpc[4], mem[4]={0,0,0,0};
    const int C = CHANNELS(_C);
    for (i=1;i<len>>1;i++)
-      x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT+2);
-   x_lp[0] = SHR32(HALF32(HALF32(*xmem+x[0][1])+x[0][0]), SIG_SHIFT+2);
-   *xmem = x[0][end-1];
+      x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT+3);
+   x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), SIG_SHIFT+3);
    if (C==2)
    {
       for (i=1;i<len>>1;i++)
-      x_lp[i] = SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT+2);
-      x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+2);
-      *xmem += x[1][end-1];
+         x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT+3);
+      x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+3);
    }
 
    _celt_autocorr(x_lp, ac, NULL, 0,
@@ -146,21 +140,21 @@ void pitch_downsample(celt_sig * restrict x[], celt_word16 * restrict x_lp, int
    fir(x_lp, lpc, x_lp, len>>1, 4, mem);
 
    mem[0]=0;
-   lpc[0]=QCONST16(.8,12);
+   lpc[0]=QCONST16(.8f,12);
    fir(x_lp, lpc, x_lp, len>>1, 1, mem);
 
 }
 
-void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_word16 * restrict y,
-                  int len, int max_pitch, int *pitch, celt_sig *xmem, int M)
+void pitch_search(const opus_val16 * restrict x_lp, opus_val16 * restrict y,
+                  int len, int max_pitch, int *pitch)
 {
    int i, j;
    int lag;
-   int best_pitch[2]={0};
-   VARDECL(celt_word16, x_lp4);
-   VARDECL(celt_word16, y_lp4);
-   VARDECL(celt_word32, xcorr);
-   celt_word32 maxcorr=1;
+   int best_pitch[2]={0,0};
+   VARDECL(opus_val16, x_lp4);
+   VARDECL(opus_val16, y_lp4);
+   VARDECL(opus_val32, xcorr);
+   opus_val32 maxcorr=1;
    int offset;
    int shift=0;
 
@@ -168,9 +162,9 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
 
    lag = len+max_pitch;
 
-   ALLOC(x_lp4, len>>2, celt_word16);
-   ALLOC(y_lp4, lag>>2, celt_word16);
-   ALLOC(xcorr, max_pitch>>1, celt_word32);
+   ALLOC(x_lp4, len>>2, opus_val16);
+   ALLOC(y_lp4, lag>>2, opus_val16);
+   ALLOC(xcorr, max_pitch>>1, opus_val32);
 
    /* Downsample by 2 again */
    for (j=0;j<len>>2;j++)
@@ -179,7 +173,7 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
       y_lp4[j] = y[2*j];
 
 #ifdef FIXED_POINT
-   shift = celt_ilog2(MAX16(celt_maxabs16(x_lp4, len>>2), celt_maxabs16(y_lp4, lag>>2)))-11;
+   shift = celt_ilog2(MAX16(1, MAX16(celt_maxabs16(x_lp4, len>>2), celt_maxabs16(y_lp4, lag>>2))))-11;
    if (shift>0)
    {
       for (j=0;j<len>>2;j++)
@@ -197,7 +191,7 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
 
    for (i=0;i<max_pitch>>2;i++)
    {
-      celt_word32 sum = 0;
+      opus_val32 sum = 0;
       for (j=0;j<len>>2;j++)
          sum = MAC16_16(sum, x_lp4[j],y_lp4[i+j]);
       xcorr[i] = MAX32(-1, sum);
@@ -209,7 +203,7 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
    maxcorr=1;
    for (i=0;i<max_pitch>>1;i++)
    {
-      celt_word32 sum=0;
+      opus_val32 sum=0;
       xcorr[i] = 0;
       if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2)
          continue;
@@ -223,7 +217,7 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
    /* Refine by pseudo-interpolation */
    if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1)
    {
-      celt_word32 a, b, c;
+      opus_val32 a, b, c;
       a = xcorr[best_pitch[0]-1];
       b = xcorr[best_pitch[0]];
       c = xcorr[best_pitch[0]+1];
@@ -231,7 +225,7 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
          offset = 1;
       else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c))
          offset = -1;
-      else 
+      else
          offset = 0;
    } else {
       offset = 0;
@@ -241,19 +235,20 @@ void pitch_search(const CELTMode *m, const celt_word16 * restrict x_lp, celt_wor
    RESTORE_STACK;
 }
 
-#ifdef ENABLE_POSTFILTER
 static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
-celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
-      int N, int *_T0, int prev_period, celt_word16 prev_gain)
+opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
+      int N, int *_T0, int prev_period, opus_val16 prev_gain)
 {
-   int k, i, T, T0, k0;
-   celt_word16 g, g0;
-   celt_word16 pg;
-   celt_word32 xy,xx,yy;
-   celt_word32 xcorr[3];
-   celt_word32 best_xy, best_yy;
+   int k, i, T, T0;
+   opus_val16 g, g0;
+   opus_val16 pg;
+   opus_val32 xy,xx,yy;
+   opus_val32 xcorr[3];
+   opus_val32 best_xy, best_yy;
    int offset;
+   int minperiod0;
 
+   minperiod0 = minperiod;
    maxperiod /= 2;
    minperiod /= 2;
    *_T0 /= 2;
@@ -275,7 +270,7 @@ celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
    best_yy = yy;
 #ifdef FIXED_POINT
       {
-         celt_word32 x2y2;
+         opus_val32 x2y2;
          int sh, t;
          x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));
          sh = celt_ilog2(x2y2)>>1;
@@ -283,15 +278,14 @@ celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
          g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
       }
 #else
-      g = g0 = xy/sqrt(1+xx*yy);
+      g = g0 = xy/celt_sqrt(1+xx*yy);
 #endif
-   k0 = 1;
    /* Look for any pitch at T/k */
    for (k=2;k<=15;k++)
    {
       int T1, T1b;
-      celt_word16 g1;
-      celt_word16 cont=0;
+      opus_val16 g1;
+      opus_val16 cont=0;
       T1 = (2*T0+k)/(2*k);
       if (T1 < minperiod)
          break;
@@ -317,7 +311,7 @@ celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
       }
 #ifdef FIXED_POINT
       {
-         celt_word32 x2y2;
+         opus_val32 x2y2;
          int sh, t;
          x2y2 = 1+MULT32_32_Q31(xx,yy);
          sh = celt_ilog2(x2y2)>>1;
@@ -325,7 +319,7 @@ celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
          g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
       }
 #else
-      g1 = xy/sqrt(1+2.f*xx*1.f*yy);
+      g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy);
 #endif
       if (abs(T1-prev_period)<=1)
          cont = prev_gain;
@@ -364,9 +358,7 @@ celt_word16 remove_doubling(celt_word16 *x, int maxperiod, int minperiod,
       pg = g;
    *_T0 = 2*T+offset;
 
-   if (*_T0<2*minperiod)
-      *_T0=2*minperiod;
+   if (*_T0<minperiod0)
+      *_T0=minperiod0;
    return pg;
 }
-
-#endif /* ENABLE_POSTFILTER */