changeset 128:f47f4c7c158c

* Add FFT data server class to provide a file cache mapping for each required set of FFT parameters and source model. Make use of it in feature extraction plugin transform, though not in other places yet. * Add zero-pad option to spectrogram layer and remove window shape option from the property box. To be revised.
author Chris Cannam
date Mon, 26 Jun 2006 16:12:11 +0000
parents 514ebb0c5c6c
children 4e38a29c13fc
files base/FFTCache.cpp base/FFTCache.h transform/FeatureExtractionPluginTransform.cpp
diffstat 3 files changed, 70 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/base/FFTCache.cpp	Mon Jun 26 16:08:01 2006 +0000
+++ b/base/FFTCache.cpp	Mon Jun 26 16:12:11 2006 +0000
@@ -99,3 +99,20 @@
     }
 }	    
 
+void
+FFTMemoryCache::setColumnAt(size_t x, float *reals, float *imags)
+{
+    float max = 0.0;
+
+    for (size_t y = 0; y < m_height; ++y) {
+        float mag = sqrtf(reals[y] * reals[y] + imags[y] * imags[y]);
+        float phase = atan2f(imags[y], reals[y]);
+        phase = princargf(phase);
+        reals[y] = mag;
+        imags[y] = phase;
+        if (mag > max) max = mag;
+    }
+
+    setColumnAt(x, reals, imags, max);
+}
+
--- a/base/FFTCache.h	Mon Jun 26 16:08:01 2006 +0000
+++ b/base/FFTCache.h	Mon Jun 26 16:12:11 2006 +0000
@@ -36,9 +36,16 @@
     virtual float getNormalizedMagnitudeAt(size_t x, size_t y) const = 0;
     virtual float getPhaseAt(size_t x, size_t y) const = 0;
 
+    virtual void getValuesAt(size_t x, size_t y, float &real, float &imaginary) const = 0;
+
     virtual bool haveSetColumnAt(size_t x) const = 0;
+
+    // may modify argument arrays
     virtual void setColumnAt(size_t x, float *mags, float *phases, float factor) = 0;
 
+    // may modify argument arrays
+    virtual void setColumnAt(size_t x, float *reals, float *imags) = 0;
+
     bool isLocalPeak(size_t x, size_t y) const {
         float mag = getMagnitudeAt(x, y);
         if (y > 0 && mag < getMagnitudeAt(x, y - 1)) return false;
@@ -98,6 +105,13 @@
         return (float(i) / 32767.0) * M_PI;
     }
     
+    virtual void getValuesAt(size_t x, size_t y, float &real, float &imag) const {
+        float mag = getMagnitudeAt(x, y);
+        float phase = getPhaseAt(x, y);
+        real = mag * cosf(phase);
+        imag = mag * sinf(phase);
+    }
+
     virtual void setNormalizationFactor(size_t x, float factor) {
         if (x < m_width) m_factor[x] = factor;
     }
@@ -132,6 +146,8 @@
         }
     }
 
+    virtual void setColumnAt(size_t x, float *reals, float *imags);
+
 private:
     size_t m_width;
     size_t m_height;
--- a/transform/FeatureExtractionPluginTransform.cpp	Mon Jun 26 16:08:01 2006 +0000
+++ b/transform/FeatureExtractionPluginTransform.cpp	Mon Jun 26 16:12:11 2006 +0000
@@ -1,4 +1,3 @@
-
 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
 
 /*
@@ -28,6 +27,8 @@
 #include "model/DenseTimeValueModel.h"
 #include "model/NoteModel.h"
 
+#include "fileio/FFTDataServer.h"
+
 #include <fftw3.h>
 
 #include <iostream>
@@ -241,6 +242,7 @@
 	buffers[ch] = new float[m_blockSize];
     }
 
+/*!!!
     float *fftInput = 0;
     fftwf_complex *fftOutput = 0;
     fftwf_plan fftPlan = 0;
@@ -256,6 +258,24 @@
             std::cerr << "ERROR: FeatureExtractionPluginTransform::run(): fftw_plan failed! Results will be garbage" << std::endl;
         }
     }
+*/
+
+    bool frequencyDomain = (m_plugin->getInputDomain() ==
+                            Vamp::Plugin::FrequencyDomain);
+    std::vector<FFTDataServer *> fftServers;
+
+    if (frequencyDomain) {
+        for (size_t ch = 0; ch < channelCount; ++ch) {
+            fftServers.push_back(FFTDataServer::getInstance
+                                 (getInput(),
+                                  channelCount == 1 ? m_channel : ch,
+                                  HanningWindow,
+                                  m_blockSize,
+                                  m_stepSize,
+                                  m_blockSize,
+                                  false));
+        }
+    }
 
     long startFrame = m_input->getStartFrame();
     long   endFrame = m_input->getEndFrame();
@@ -265,7 +285,7 @@
 
     while (1) {
 
-        if (fftPlan) {
+        if (frequencyDomain) {
             if (blockFrame - int(m_blockSize)/2 > endFrame) break;
         } else {
             if (blockFrame >= endFrame) break;
@@ -281,15 +301,22 @@
 	// channelCount is either m_input->channelCount or 1
 
         for (size_t ch = 0; ch < channelCount; ++ch) {
-            if (fftPlan) {
-                getFrames(ch, channelCount, 
-                          blockFrame - m_blockSize/2, m_blockSize, buffers[ch]);
+//!!!            if (fftPlan) {
+//                getFrames(ch, channelCount, 
+//                          blockFrame - m_blockSize/2, m_blockSize, buffers[ch]);
+      
+            if (frequencyDomain) {
+                int column = (blockFrame - startFrame) / m_stepSize;
+                for (size_t i = 0; i < m_blockSize/2; ++i) {
+                    fftServers[ch]->getValuesAt
+                        (column, i, buffers[ch][i*2], buffers[ch][i*2+1]);
+                }
             } else {
                 getFrames(ch, channelCount, 
-                           blockFrame, m_blockSize, buffers[ch]);
+                          blockFrame, m_blockSize, buffers[ch]);
             }                
         }
-        
+    /*!!!
         if (fftPlan) {
             for (size_t ch = 0; ch < channelCount; ++ch) {
                 for (size_t i = 0; i < m_blockSize; ++i) {
@@ -308,7 +335,7 @@
                 }
             }
         }
-
+    */
 	Vamp::Plugin::FeatureSet features = m_plugin->process
 	    (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate));
 
@@ -325,13 +352,13 @@
 
 	blockFrame += m_stepSize;
     }
-
+/*!!!
     if (fftPlan) {
         fftwf_destroy_plan(fftPlan);
         fftwf_free(fftInput);
         fftwf_free(fftOutput);
     }
-
+*/
     Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures();
 
     for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) {