Fixed stereo version of the pitch estimator
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 10 Dec 2007 06:57:19 +0000 (17:57 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 10 Dec 2007 06:57:19 +0000 (17:57 +1100)
libcelt/celt.c
libcelt/pitch.c
libcelt/pitch.h
libcelt/testcelt.c

index 50b5d6e..19ef1f8 100644 (file)
@@ -88,7 +88,7 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode)
    ec_enc_init(&st->enc,&st->buf);
 
    mdct_init(&st->mdct_lookup, 2*N);
-   st->fft = spx_fft_init(MAX_PERIOD);
+   st->fft = spx_fft_init(MAX_PERIOD*C);
    
    st->window = celt_alloc(2*N*sizeof(float));
    st->in_mem = celt_alloc(N*C*sizeof(float));
@@ -237,7 +237,7 @@ int celt_encode(CELTEncoder *st, short *pcm)
          in[C*(B*N+i)+c] *= st->window[N+i];
       }
    }
-   find_spectral_pitch(st->fft, in, st->out_mem, MAX_PERIOD, (B+1)*N, &pitch_index);
+   find_spectral_pitch(st->fft, in, st->out_mem, MAX_PERIOD, (B+1)*N, C, &pitch_index);
    ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(B+1)*N);
    
    /* Compute MDCTs of the pitch part */
@@ -314,6 +314,8 @@ int celt_encode(CELTEncoder *st, short *pcm)
          {
             float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
             st->preemph_memD[c] = tmp;
+            if (tmp > 32767) tmp = 32767;
+            if (tmp < -32767) tmp = -32767;
             pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
          }
       }
@@ -443,6 +445,8 @@ static void celt_decode_lost(CELTDecoder *st, short *pcm)
          {
             float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
             st->preemph_memD[c] = tmp;
+            if (tmp > 32767) tmp = 32767;
+            if (tmp < -32767) tmp = -32767;
             pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
          }
       }
@@ -520,6 +524,8 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
          {
             float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
             st->preemph_memD[c] = tmp;
+            if (tmp > 32767) tmp = 32767;
+            if (tmp < -32767) tmp = -32767;
             pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
          }
       }
index decbac9..e32ead6 100644 (file)
 #include "pitch.h"
 #include "psy.h"
 
-void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int *pitch)
+void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int C, int *pitch)
 {
+   int c;
    int n2 = lag/2;
-   float xx[lag];
-   float X[lag];
-   float Y[lag];
-   float curve[n2];
+   float xx[lag*C];
+   float yy[lag*C];
+   float X[lag*C];
+   float Y[lag*C];
+   float curve[n2*C];
    int i;
    
-   for (i=0;i<lag;i++)
+   for (i=0;i<C*lag;i++)
       xx[i] = 0;
-   for (i=0;i<len;i++)
-      xx[i] = x[i];
-   
+   for (c=0;c<C;c++)
+   {
+      for (i=0;i<len;i++)
+         xx[c*lag+i] = x[C*i+c];
+      for (i=0;i<lag;i++)
+         yy[c*lag+i] = y[C*i+c];
+      
+   }
    spx_fft(fft, xx, X);
-   spx_fft(fft, y, Y);
+   spx_fft(fft, yy, Y);
    
-   compute_masking(X, curve, lag, 44100);
+   compute_masking(X, curve, lag*C, 44100);
    
    X[0] = 0;
-   for (i=1;i<lag/2;i++)
+   for (i=1;i<C*n2;i++)
    {
       float n;
       //n = 1.f/(1e1+sqrt(sqrt((X[2*i-1]*X[2*i-1] + X[2*i  ]*X[2*i  ])*(Y[2*i-1]*Y[2*i-1] + Y[2*i  ]*Y[2*i  ]))));
@@ -58,8 +65,8 @@ void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int *p
       X[2*i-1] = (X[2*i-1]*Y[2*i-1] + X[2*i  ]*Y[2*i  ])*n;
       X[2*i  ] = (- X[2*i  ]*Y[2*i-1] + tmp*Y[2*i  ])*n;
    }
-   X[lag-1] = 0;
-   X[0] = X[lag-1] = 0;
+   X[C*lag-1] = 0;
+   X[0] = X[C*lag-1] = 0;
    spx_ifft(fft, X, xx);
    
    float max_corr=-1e10;
index b61bcce..5e222b9 100644 (file)
@@ -23,6 +23,6 @@
 #ifndef _PITCH_H
 #define _PITCH_H
 
-void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int *pitch);
+void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int C, int *pitch);
 
 #endif
index a379d2a..a4f50ec 100644 (file)
@@ -59,9 +59,9 @@ int main(int argc, char *argv[])
    {
       fread(in, sizeof(short), FRAME_SIZE*CHANNELS, fin);
       celt_encode(enc, in);
+#if 1
       data = celt_encoder_get_bytes(enc, &len);
       //printf ("%d\n", len);
-#if 1
       /* this is to simulate packet loss */
       if (rand()%100==-1)
          celt_decode(dec, NULL, len, in);