shithub: opus

Download patch

ref: 6e9058adb94b0053c66fa1271928e13b817b0f03
parent: 70c8ffdd5500a07a890762fdcd7b11df5d7b2ab2
author: Jean-Marc Valin <[email protected]>
date: Fri Dec 7 09:59:06 EST 2007

Nearly working cheating decoder.

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -195,6 +195,8 @@
             norm[j] = X[j] * n;
       } else {
          float n = sqrt(B*(eBands[i+1]-eBands[i]));
+         for (j=B*eBands[i];j<B*eBands[i+1];j++)
+            X[j] = 0;
          //copy_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), -q, norm, B, eBands[i], dec);
          for (j=B*eBands[i];j<B*eBands[i+1];j++)
             norm[j] = X[j] * n;
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -41,6 +41,12 @@
 
 #define MAX_PERIOD 1024
 
+/* This is only for cheating until the decoder is complete */
+float cheating_ebands[100];
+float cheating_pitch_gains[100];
+float cheating_period;
+
+
 struct CELTEncoder {
    const CELTMode *mode;
    int frame_size;
@@ -231,6 +237,12 @@
    //quantise_pitch(gains, PBANDS);
    pitch_quant_bands(st->mode, X, P, gains);
    
+   cheating_period = pitch_index;
+   for (i=0;i<st->mode->nbEBands;i++)
+      cheating_ebands[i] = bandE[i];
+   for (i=0;i<st->mode->nbPBands;i++)
+      cheating_pitch_gains[i] = gains[i];
+
    //for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");
    /* Subtract the pitch prediction from the signal to encode */
    for (i=0;i<B*N;i++)
@@ -288,6 +300,13 @@
    return 0;
 }
 
+char *celt_encoder_get_bytes(CELTEncoder *st, int *nbBytes)
+{
+   *nbBytes = ec_byte_bytes(&st->buf);
+   return ec_byte_get_buffer(&st->buf);
+}
+
+
 /****************************************************************************/
 /*                                Decoder                                   */
 /****************************************************************************/
@@ -379,8 +398,11 @@
    ec_dec_init(&dec,&buf);
    
    /* Get band energies */
-   
+   for (i=0;i<st->mode->nbEBands;i++)
+      bandE[i] = cheating_ebands[i];
+
    /* Get the pitch index */
+   pitch_index = cheating_period;
    
    /* Pitch MDCT */
    compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index, P, N, B);
@@ -394,7 +416,9 @@
    }
 
    /* Get the pitch gains */
-   
+   for (i=0;i<st->mode->nbPBands;i++)
+      gains[i] = cheating_pitch_gains[i];
+
    /* Apply pitch gains */
    pitch_quant_bands(st->mode, X, P, gains);
 
@@ -431,5 +455,6 @@
          pcm[i*N+j] = (short)floor(.5+tmp);
       }
    }
+   //printf ("\n");
 }
 
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -47,6 +47,7 @@
 
 int celt_encode(CELTEncoder *st, short *pcm);
 
+char *celt_encoder_get_bytes(CELTEncoder *st, int *nbBytes);
 
 /* Decoder stuff */
 
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -41,7 +41,8 @@
    char *inFile, *outFile;
    FILE *fin, *fout;
    short in[FRAME_SIZE];
-   CELTEncoder *st;
+   CELTEncoder *enc;
+   CELTDecoder *dec;
    
    inFile = argv[1];
    fin = fopen(inFile, "rb");
@@ -48,15 +49,21 @@
    outFile = argv[2];
    fout = fopen(outFile, "wb+");
    
-   st = celt_encoder_new(celt_mode1);
+   enc = celt_encoder_new(celt_mode1);
+   dec = celt_decoder_new(celt_mode1);
    
    while (!feof(fin))
    {
+      int len;
+      char *data;
       fread(in, sizeof(short), FRAME_SIZE, fin);
-      celt_encode(st, in);
+      celt_encode(enc, in);
+      data = celt_encoder_get_bytes(enc, &len);
+      //celt_decode(dec, data, len, in);
       fwrite(in, sizeof(short), FRAME_SIZE, fout);
    }
-   celt_encoder_destroy(st);
+   celt_encoder_destroy(enc);
+   celt_decoder_destroy(dec);
    fclose(fin);
    fclose(fout);
    return 0;
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -221,6 +221,11 @@
             s = -1;
       }
    }
+   //printf ("e%d e%d ", s, best);
+   if (s==-1)
+      ec_enc_uint(enc,1,1);
+   else
+      ec_enc_uint(enc,0,1);
    ec_enc_uint(enc,best/B,N0-N/B);
    //printf ("%d %f\n", best, best_score);
    if (K==0)
@@ -294,3 +299,47 @@
       x[i] = p[i] + g*y[i];
 }
 
+void copy_unquant(float *x, int N, int K, float *Y, int B, int N0, ec_dec *dec)
+{
+   int i,j;
+   int s;
+   int best;
+   float E;
+   if (ec_dec_uint(dec, 1) == 0)
+      s = 1;
+   else
+      s = -1;
+   
+   best = B*ec_dec_uint(dec, N0-N/B);
+   printf ("d%d d%d ", s, best);
+
+   if (K==0)
+   {
+      E = 1e-10;
+      for (j=0;j<N;j++)
+      {
+         x[j] = s*Y[best+j];
+         E += x[j]*x[j];
+      }
+      E = 1/sqrt(E);
+      for (j=0;j<N;j++)
+         x[j] *= E;
+   } else {
+      float P[N];
+      float pred_gain;
+      if (K>4)
+         pred_gain = .5;
+      else
+         pred_gain = pg[K];
+      E = 1e-10;
+      for (j=0;j<N;j++)
+      {
+         P[j] = s*Y[best+j];
+         E += P[j]*P[j];
+      }
+      E = .8/sqrt(E);
+      for (j=0;j<N;j++)
+         P[j] *= E;
+      alg_unquant(x, N, K, P, dec);
+   }
+}
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -46,4 +46,5 @@
 /* Finds the right offset into Y and copy it */
 void copy_quant(float *x, int N, int K, float *Y, int B, int N0, ec_enc *enc);
 
+void copy_unquant(float *x, int N, int K, float *Y, int B, int N0, ec_dec *dec);
 #endif /* VQ_H */