shithub: opus

Download patch

ref: af8402e033360256d34689cd822cd75291ff4bef
parent: df3cb9be1f623f4b8827ebb5faafadd6f34600df
author: Jean-Marc Valin <[email protected]>
date: Fri Feb 22 07:13:59 EST 2008

Fixed stuff that got broken during the forward-backward split of the FFT

--- a/libcelt/_kiss_fft_guts.h
+++ b/libcelt/_kiss_fft_guts.h
@@ -67,8 +67,8 @@
       do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
           (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
 #   define C_MULC(m,a,b) \
-               do{ (m).r = sround( smul((a).r,(b).r) + smul((a).i,(b).i) ); \
-               (m).i = smul((a).i,(b).r) - sround( smul((a).r,(b).i) ); }while(0)
+      do{ (m).r = sround( smul((a).r,(b).r) + smul((a).i,(b).i) ); \
+          (m).i = sround( smul((a).i,(b).r) - smul((a).r,(b).i) ); }while(0)
 
 #   define C_MUL4(m,a,b) \
                do{ (m).r = PSHR32( smul((a).r,(b).r) - smul((a).i,(b).i),17 ); \
@@ -84,6 +84,44 @@
 #   define C_MULBYSCALAR( c, s ) \
     do{ (c).r =  sround( smul( (c).r , s ) ) ;\
         (c).i =  sround( smul( (c).i , s ) ) ; }while(0)
+
+               
+#define L1 32767
+#define L2 -7651
+#define L3 8277
+#define L4 -626
+
+static inline celt_word16_t _celt_cos_pi_2(celt_word16_t x)
+{
+   celt_word16_t x2;
+   
+   x2 = MULT16_16_P15(x,x);
+   return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2
+                                                                                ))))))));
+}
+
+static inline celt_word16_t celt_cos_norm(celt_word32_t x)
+{
+   x = x&0x0001ffff;
+   if (x>SHL32(EXTEND32(1), 16))
+      x = SUB32(SHL32(EXTEND32(1), 17),x);
+   if (x&0x00007fff)
+   {
+      if (x<SHL32(EXTEND32(1), 15))
+      {
+         return _celt_cos_pi_2(EXTRACT16(x));
+      } else {
+         return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
+      }
+   } else {
+      if (x&0x0000ffff)
+         return 0;
+      else if (x&0x0001ffff)
+         return -32767;
+      else
+         return 32767;
+   }
+}
 
 #else  /* not FIXED_POINT*/
 
--- a/libcelt/kiss_fft.h
+++ b/libcelt/kiss_fft.h
@@ -33,7 +33,7 @@
 
 #ifdef FIXED_POINT
 #include "arch.h"	
-#  define kiss_fft_scalar spx_int16_t
+#  define kiss_fft_scalar celt_int16_t
 #else
 # ifndef kiss_fft_scalar
 /*  default is float */
--- a/tests/dft-test.c
+++ b/tests/dft-test.c
@@ -25,13 +25,17 @@
                 im = -im;
 
 #ifdef FIXED_POINT
-            re /= nfft;
-            im /= nfft;
+            if (!isinverse)
+            {
+               re /= nfft;
+               im /= nfft;
+            }
 #endif            
 
             ansr += in[k].r * re - in[k].i * im;
             ansi += in[k].r * im + in[k].i * re;
         }
+        /*printf ("%d %d ", (int)ansr, (int)ansi);*/
         difr = ansr - out[bin].r;
         difi = ansi - out[bin].i;
         errpow += difr*difr + difi*difi;
@@ -55,9 +59,21 @@
     }
 
     if (isinverse)
+    {
+       for (k=0;k<nfft;++k) {
+          in[k].r /= nfft;
+          in[k].i /= nfft;
+       }
+    }
+    
+    /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
+       
+    if (isinverse)
        kiss_ifft(cfg,in,out);
     else
        kiss_fft(cfg,in,out);
+
+    /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
 
     check(in,out,nfft,isinverse);