shithub: opus

Download patch

ref: 2c1d2f5bcc17d1442bcde442cbdfc6808e748603
parent: b8e5c4c658af6b69ecfd8a97610899d840588428
author: Jean-Marc Valin <[email protected]>
date: Fri Feb 22 16:45:16 EST 2008

MDCT now scales down by N/2 instead of N/4. The factor two is moved to the
overlap-add during synthesis.

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -210,9 +210,9 @@
          for (j=0;j<2*N;j++)
             x[j] = window[j]*x[j];
          for (j=0;j<overlap;j++)
-            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = x[N4+j]+mdct_overlap[C*j+c];
+            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = 2*(x[N4+j]+mdct_overlap[C*j+c]);
          for (j=0;j<2*N4;j++)
-            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = x[j+N4+overlap];
+            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = 2*x[j+N4+overlap];
          for (j=0;j<overlap;j++)
             mdct_overlap[C*j+c] = x[N+N4+j];
       }
--- a/libcelt/mdct.c
+++ b/libcelt/mdct.c
@@ -93,8 +93,8 @@
    {
       float re, im;
       /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
-      re = -in[N2+N4+2*i] - in[N2+N4-2*i-1];
-      im = -in[N4+2*i]    + in[N4-2*i-1];
+      re = -.5*(in[N2+N4+2*i] + in[N2+N4-2*i-1]);
+      im = -.5*(in[N4+2*i]    - in[N4-2*i-1]);
       out[2*i]   = re*l->trig[i]  -  im*l->trig[i+N4];
       out[2*i+1] = im*l->trig[i]  +  re*l->trig[i+N4];
    }
@@ -102,8 +102,8 @@
    {
       float re, im;
       /* Real part arranged as a-bR, Imag part arranged as -c-dR */
-      re =   in[2*i-N4] - in[N2+N4-2*i-1];
-      im = -(in[N4+2*i] + in[N+N4-2*i-1]);
+      re =  .5*(in[2*i-N4] - in[N2+N4-2*i-1]);
+      im = -.5*(in[N4+2*i] + in[N+N4-2*i-1]);
       out[2*i]   = re*l->trig[i]  -  im*l->trig[i+N4];
       out[2*i+1] = im*l->trig[i]  +  re*l->trig[i+N4];
    }
@@ -147,6 +147,7 @@
       float re, im;
       re = f[2*i];
       im = f[2*i+1];
+      /* We'd scale up by 2 here, but instead it's done when mixing the windows */
       f[2*i]   = re*l->trig[i] + im*l->trig[i+N4];
       f[2*i+1] = im*l->trig[i] - re*l->trig[i+N4];
    }
--- a/tests/dft-test.c
+++ b/tests/dft-test.c
@@ -5,11 +5,12 @@
 #include <stdio.h>
 #include "kiss_fft.h"
 
+int ret = 0;
 
 void check(kiss_fft_cpx  * in,kiss_fft_cpx  * out,int nfft,int isinverse)
 {
     int bin,k;
-    double errpow=0,sigpow=0;
+    double errpow=0,sigpow=0, snr;
     
     for (bin=0;bin<nfft;++bin) {
         double ansr = 0;
@@ -41,7 +42,12 @@
         errpow += difr*difr + difi*difi;
         sigpow += ansr*ansr+ansi*ansi;
     }
-    printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,10*log10(sigpow/errpow) );
+    snr = 10*log10(sigpow/errpow);
+    printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
+    if (snr<60) {
+       printf( "** poor snr: %f ** \n", snr);
+       ret = 1;
+    }
 }
 
 void test1d(int nfft,int isinverse)
@@ -109,5 +115,5 @@
         test1d(105,0);
         test1d(105,1);
     }
-    return 0;
+    return ret;
 }
--- a/tests/mdct-test.c
+++ b/tests/mdct-test.c
@@ -5,12 +5,12 @@
 #include <stdio.h>
 #include "mdct.h"
 
-
+int ret = 0;
 void check(float  * in,float  * out,int nfft,int isinverse)
 {
     int bin,k;
     double errpow=0,sigpow=0;
-    
+    double snr;
     for (bin=0;bin<nfft/2;++bin) {
         double ansr = 0;
         double difr;
@@ -19,7 +19,7 @@
            double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
            double re = cos(phase);
             
-           re /= nfft/4;
+           re /= nfft/2;
 
            ansr += in[k] * re;
         }
@@ -28,7 +28,12 @@
         errpow += difr*difr;
         sigpow += ansr*ansr;
     }
-    printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,10*log10(sigpow/errpow) );
+    snr = 10*log10(sigpow/errpow);
+    printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
+    if (snr<60) {
+       printf( "** poor snr: %f **\n", snr);
+       ret = 1;
+    }
 }
 
 void check_inv(float  * in,float  * out,int nfft,int isinverse)
@@ -35,7 +40,7 @@
 {
    int bin,k;
    double errpow=0,sigpow=0;
-    
+   double snr;
    for (bin=0;bin<nfft;++bin) {
       double ansr = 0;
       double difr;
@@ -43,7 +48,9 @@
       for (k=0;k<nfft/2;++k) {
          double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
          double re = cos(phase);
-            
+
+         //re *= 2;
+
          ansr += in[k] * re;
       }
       /*printf ("%f %f\n", ansr, out[bin]);*/
@@ -51,7 +58,12 @@
       errpow += difr*difr;
       sigpow += ansr*ansr;
    }
-   printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,10*log10(sigpow/errpow) );
+   snr = 10*log10(sigpow/errpow);
+   printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
+   if (snr<60) {
+      printf( "** poor snr: %f **\n", snr);
+      ret = 1;
+   }
 }
 
 
@@ -112,13 +124,20 @@
     }else{
         test1d(32,0);
         test1d(32,1);
-        exit(0);
-        test1d(36,0);
-        test1d(36,1);
-        test1d(50,0);
-        test1d(50,1);
+        test1d(40,0);
+        test1d(40,1);
+        test1d(56,0);
+        test1d(56,1);
         test1d(120,0);
         test1d(120,1);
+        test1d(240,0);
+        test1d(240,1);
+        test1d(256,0);
+        test1d(256,1);
+        test1d(480,0);
+        test1d(480,1);
+        test1d(512,0);
+        test1d(512,1);
     }
-    return 0;
+    return ret;
 }
--- a/tests/real-fft-test.c
+++ b/tests/real-fft-test.c
@@ -10,6 +10,8 @@
 #include <stdio.h>
 #include <string.h>
 
+int ret=0;
+
 static double cputime(void)
 {
     struct tms t;
@@ -44,9 +46,9 @@
 
     }
     snr = 10*log10( sigpow / noisepow );
-    if (snr<10) {
-        printf( "\npoor snr: %f\n", snr);
-        exit(1);
+    if (snr<60) {
+        printf( "** poor snr: %f **\n", snr);
+        ret = 1;
     }
     return snr;
 }
@@ -63,9 +65,9 @@
         noisepow += err * err;
     }
     snr = 10*log10( sigpow / noisepow );
-    if (snr<10) {
+    if (snr<60) {
         printf( "\npoor snr: %f\n", snr);
-        exit(1);
+        ret = 1;
     }
     return snr;
 }
@@ -184,5 +186,5 @@
     free(kiss_fft_state);
     free(kiss_fftr_state);
 
-    return 0;
+    return ret;
 }