shithub: opus

Download patch

ref: 4841a0a02b4ad2d9625602ca4d7f5bd63753bc53
parent: c4541ae786b4d7f39bca6779fee55225b26307d0
author: Jean-Marc Valin <[email protected]>
date: Mon Dec 3 08:54:30 EST 2007

Intra-frame prediction

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -32,6 +32,7 @@
 #include <math.h>
 #include "bands.h"
 #include "vq.h"
+#include "cwrs.h"
 
 const int qbank[NBANDS+2] =   {0, 2, 4, 6, 8, 12, 16, 20, 24, 28, 36, 44, 52, 68, 84, 116, 128};
 
@@ -144,15 +145,24 @@
 
 void quant_bands(float *X, int B, float *P)
 {
-   int i;
+   int i, j;
+   float norm[B*qbank[NBANDS+1]];
+   
    for (i=0;i<NBANDS;i++)
    {
       int q;
       q =qpulses[i];
       if (q) {
+         float n = sqrt(B*(qbank[i+1]-qbank[i]));
          alg_quant2(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, P+B*qbank[i]);
+         for (j=B*qbank[i];j<B*qbank[i+1];j++)
+            norm[j] = X[j] * n;
       } else {
-         noise_quant(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, P+B*qbank[i]);
+         float n = sqrt(B*(qbank[i+1]-qbank[i]));
+         copy_quant(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, norm, B, qbank[i]);
+         for (j=B*qbank[i];j<B*qbank[i+1];j++)
+            norm[j] = X[j] * n;
+         //noise_quant(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, P+B*qbank[i]);
       }
    }
    for (i=B*qbank[NBANDS];i<B*qbank[NBANDS+1];i++)
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -218,3 +218,39 @@
       x[i] *= E;
    }
 }
+
+/* Finds the right offset into Y and copy it */
+void copy_quant(float *x, int N, int K, float *Y, int B, int N0)
+{
+   int i,j;
+   int best=0;
+   float best_score=-1e15;
+   float E;
+   for (i=0;i<N0*B-N;i+=B)
+   {
+      int j;
+      float xy=0, yy=0;
+      float score;
+      for (j=0;j<N;j++)
+      {
+         xy += x[j]*Y[i+j];
+         yy += Y[i+j]*Y[i+j];
+      }
+      score = xy*xy/(.1*yy);
+      if (score > best_score)
+      {
+         best_score = score;
+         best = i;
+      }
+   }
+   //printf ("%d\n", best);
+   E = 1e-10;
+   for (j=0;j<N;j++)
+   {
+      x[j] = Y[best+j];
+      E += x[j]*x[j];
+   }
+   E = 1/sqrt(E);
+   for (j=0;j<N;j++)
+      x[j] *= E;
+}
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -44,5 +44,7 @@
 /* Just replace the band with noise of unit energy */
 void noise_quant(float *x, int N, int K, float *p);
 
+/* Finds the right offset into Y and copy it */
+void copy_quant(float *x, int N, int K, float *Y, int B, int N0);
 
 #endif /* VQ_H */