changeset 67:eb530055ed55

* Add support for frequency-domain inputs to Vamp plugins
author Chris Cannam
date Fri, 31 Mar 2006 17:40:14 +0000
parents 7afcfe666910
children 8e8c2981a189
files transform/FeatureExtractionPluginTransform.cpp
diffstat 1 files changed, 44 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/transform/FeatureExtractionPluginTransform.cpp	Fri Mar 31 15:56:35 2006 +0000
+++ b/transform/FeatureExtractionPluginTransform.cpp	Fri Mar 31 17:40:14 2006 +0000
@@ -21,11 +21,14 @@
 #include "vamp-sdk/Plugin.h"
 
 #include "base/Model.h"
+#include "base/Window.h"
 #include "model/SparseOneDimensionalModel.h"
 #include "model/SparseTimeValueModel.h"
 #include "model/DenseThreeDimensionalModel.h"
 #include "model/DenseTimeValueModel.h"
 
+#include <fftw3.h>
+
 #include <iostream>
 
 FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel,
@@ -205,6 +208,22 @@
 	buffers[ch] = new float[blockSize];
     }
 
+    double *fftInput = 0;
+    fftw_complex *fftOutput = 0;
+    fftw_plan fftPlan = 0;
+    Window<double> windower(HanningWindow, blockSize);
+
+    if (m_plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) {
+
+        fftInput = (double *)fftw_malloc(blockSize * sizeof(double));
+        fftOutput = (fftw_complex *)fftw_malloc(blockSize * sizeof(fftw_complex));
+        fftPlan = fftw_plan_dft_r2c_1d(blockSize, fftInput, fftOutput,
+                                       FFTW_ESTIMATE);
+        if (!fftPlan) {
+            std::cerr << "ERROR: FeatureExtractionPluginTransform::run(): fftw_plan failed! Results will be garbage" << std::endl;
+        }
+    }
+
     size_t startFrame = m_input->getStartFrame();
     size_t   endFrame = m_input->getEndFrame();
     size_t blockFrame = startFrame;
@@ -240,6 +259,25 @@
 	    }
 	}
 
+        if (fftPlan) {
+            for (size_t ch = 0; ch < channelCount; ++ch) {
+                for (size_t i = 0; i < blockSize; ++i) {
+                    fftInput[i] = buffers[ch][i];
+                }
+                windower.cut(fftInput);
+                for (size_t i = 0; i < blockSize/2; ++i) {
+                    double temp = fftInput[i];
+                    fftInput[i] = fftInput[i + blockSize/2];
+                    fftInput[i + blockSize/2] = temp;
+                }
+                fftw_execute(fftPlan);
+                for (size_t i = 0; i < blockSize/2; ++i) {
+                    buffers[ch][i*2] = fftOutput[i][0];
+                    buffers[ch][i*2 + 1] = fftOutput[i][1];
+                }
+            }
+        }
+
 	Vamp::Plugin::FeatureSet features = m_plugin->process
 	    (buffers, Vamp::RealTime::frame2RealTime(blockFrame, sampleRate));
 
@@ -257,6 +295,12 @@
 	blockFrame += stepSize;
     }
 
+    if (fftPlan) {
+        fftw_destroy_plan(fftPlan);
+        fftw_free(fftInput);
+        fftw_free(fftOutput);
+    }
+
     Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures();
 
     for (size_t fi = 0; fi < features[m_outputFeatureNo].size(); ++fi) {