096ef53d04f2 — Chris Cannam 3 years ago
Another lookup table
1 files changed, 43 insertions(+), 9 deletions(-)

M src/FFT.cpp
M src/FFT.cpp +43 -9
@@ 1659,6 1659,11 @@ public:
         m_d = allocate_and_zero<double>(m_half + 1);
         m_cos = allocate_and_zero<double>(m_half / 2);
         m_sin = allocate_and_zero<double>(m_half / 2);
+        m_blockTableSize = 16;
+        m_sin1 = allocate_and_zero<double>(m_blockTableSize);
+        m_sin2 = allocate_and_zero<double>(m_blockTableSize);
+        m_cos1 = allocate_and_zero<double>(m_blockTableSize);
+        m_cos2 = allocate_and_zero<double>(m_blockTableSize);
         m_vr = allocate_and_zero<double>(m_half);
         m_vi = allocate_and_zero<double>(m_half);
         makeTables();

          
@@ 1672,6 1677,10 @@ public:
         deallocate(m_d);
         deallocate(m_cos);
         deallocate(m_sin);
+        deallocate(m_sin1);
+        deallocate(m_sin2);
+        deallocate(m_cos1);
+        deallocate(m_cos2);
         deallocate(m_vr);
         deallocate(m_vi);
     }

          
@@ 1820,6 1829,11 @@ private:
     double *m_d;
     double *m_cos;
     double *m_sin;
+    int m_blockTableSize;
+    double *m_sin1;
+    double *m_sin2;
+    double *m_cos1;
+    double *m_cos2;
     double *m_vr;
     double *m_vi;
 

          
@@ 1849,7 1863,16 @@ private:
             m_table[i] = k;
         }
 
-        // additional factors for real-complex transform
+        // sin and cos tables for complex fft
+        for (i = 0; i < m_blockTableSize; ++i) {
+            double phase = 2.0 * M_PI / pow(2.0, double(i + 1));
+            m_sin1[i] = sin(phase);
+            m_sin2[i] = sin(2.0 * phase);
+            m_cos1[i] = cos(phase);
+            m_cos2[i] = cos(2.0 * phase);
+        }
+        
+        // sin and cos tables for real-complex transform
         for (i = 0; i < n/2; ++i) {
             double phase = M_PI * (double(i + 1) / double(m_half) + 0.5);
             m_cos[i] = cos(phase);

          
@@ 1929,9 1952,7 @@ private:
         int i, j, k, m;
         int blockSize, blockEnd;
         double tr, ti;
-
-        double angle = 2.0 * M_PI;
-        if (inverse) angle = -angle;
+        double ifactor = (inverse ? -1.0 : 1.0);
 
         // because we are at heart a real-complex fft only
         const int n = m_half;

          
@@ 1953,14 1974,27 @@ private:
         }
         
         blockEnd = 1;
+
+        int ix = 0;
         
         for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
+
+            double sm1, sm2, cm1, cm2;
+
+            if (ix < m_blockTableSize) {
+                sm1 = ifactor * m_sin1[ix];
+                sm2 = ifactor * m_sin2[ix];
+                cm1 = m_cos1[ix];
+                cm2 = m_cos2[ix];
+                ++ix;
+            } else {
+                double delta = 2.0 * M_PI / double(blockSize);
+                sm1 = ifactor * sin(delta);
+                sm2 = ifactor * sin(2.0 * delta);
+                cm1 = cos(delta);
+                cm2 = cos(2.0 * delta);
+            }
             
-            double delta = angle / double(blockSize);
-            double sm2 = -sin(-2 * delta);
-            double sm1 = -sin(-delta);
-            double cm2 = cos(-2 * delta);
-            double cm1 = cos(-delta);
             double w = 2 * cm1;
             double ar[3], ai[3];