changeset 47:be8fdfe25693

* Change input buffers arg to process from float ** to const float *const * to avoid plugins modifying their input data * Some improvements to comments * Fix stupidity in frequency-domain input passing (there are n/2+1 values, not n/2)
author cannam
date Fri, 08 Dec 2006 17:39:32 +0000
parents 2858c897d90f
children f46bf5e0fa42
files examples/AmplitudeFollower.cpp examples/AmplitudeFollower.h examples/PercussionOnsetDetector.cpp examples/PercussionOnsetDetector.h examples/SpectralCentroid.cpp examples/SpectralCentroid.h examples/ZeroCrossing.cpp examples/ZeroCrossing.h host/vamp-simple-host.cpp vamp-sdk/Plugin.h vamp-sdk/PluginAdapter.cpp vamp-sdk/PluginAdapter.h vamp-sdk/PluginBase.h vamp-sdk/PluginHostAdapter.cpp vamp-sdk/PluginHostAdapter.h vamp/vamp.h
diffstat 16 files changed, 87 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/examples/AmplitudeFollower.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/AmplitudeFollower.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -188,7 +188,8 @@
 }
 
 AmplitudeFollower::FeatureSet
-AmplitudeFollower::process(float **inputBuffers, Vamp::RealTime timestamp)
+AmplitudeFollower::process(const float *const *inputBuffers,
+                           Vamp::RealTime timestamp)
 {
     if (m_stepSize == 0) {
 	cerr << "ERROR: AmplitudeFollower::process: "
--- a/examples/AmplitudeFollower.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/AmplitudeFollower.h	Fri Dec 08 17:39:32 2006 +0000
@@ -62,7 +62,8 @@
     float getParameter(std::string paramname) const;
     void setParameter(std::string paramname, float newval);
 
-    FeatureSet process(float **inputBuffers, Vamp::RealTime timestamp);
+    FeatureSet process(const float *const *inputBuffers,
+                       Vamp::RealTime timestamp);
 
     FeatureSet getRemainingFeatures();
 
--- a/examples/PercussionOnsetDetector.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/PercussionOnsetDetector.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -213,7 +213,8 @@
 }
 
 PercussionOnsetDetector::FeatureSet
-PercussionOnsetDetector::process(float **inputBuffers, Vamp::RealTime ts)
+PercussionOnsetDetector::process(const float *const *inputBuffers,
+                                 Vamp::RealTime ts)
 {
     if (m_stepSize == 0) {
 	cerr << "ERROR: PercussionOnsetDetector::process: "
--- a/examples/PercussionOnsetDetector.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/PercussionOnsetDetector.h	Fri Dec 08 17:39:32 2006 +0000
@@ -65,7 +65,8 @@
 
     OutputList getOutputDescriptors() const;
 
-    FeatureSet process(float **inputBuffers, Vamp::RealTime timestamp);
+    FeatureSet process(const float *const *inputBuffers,
+                       Vamp::RealTime timestamp);
 
     FeatureSet getRemainingFeatures();
 
--- a/examples/SpectralCentroid.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/SpectralCentroid.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -126,7 +126,7 @@
 }
 
 SpectralCentroid::FeatureSet
-SpectralCentroid::process(float **inputBuffers, Vamp::RealTime)
+SpectralCentroid::process(const float *const *inputBuffers, Vamp::RealTime)
 {
     if (m_stepSize == 0) {
 	cerr << "ERROR: SpectralCentroid::process: "
@@ -137,7 +137,7 @@
 
     double numLin = 0.0, numLog = 0.0, denom = 0.0;
 
-    for (size_t i = 1; i < m_blockSize/2; ++i) {
+    for (size_t i = 1; i <= m_blockSize/2; ++i) {
 	double freq = (double(i) * m_inputSampleRate) / m_blockSize;
 	double real = inputBuffers[0][i*2];
 	double imag = inputBuffers[0][i*2 + 1];
@@ -154,12 +154,18 @@
     if (denom != 0.0) {
 	float centroidLin = float(numLin / denom);
 	float centroidLog = powf(10, float(numLog / denom));
+
 	Feature feature;
 	feature.hasTimestamp = false;
-	feature.values.push_back(centroidLog);
+        if (!isnan(centroidLog) && !isinf(centroidLog)) {
+            feature.values.push_back(centroidLog);
+        }
 	returnFeatures[0].push_back(feature);
+
         feature.values.clear();
-	feature.values.push_back(centroidLin);
+        if (!isnan(centroidLin) && !isinf(centroidLin)) {
+            feature.values.push_back(centroidLin);
+        }
 	returnFeatures[1].push_back(feature);
     }
 
--- a/examples/SpectralCentroid.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/SpectralCentroid.h	Fri Dec 08 17:39:32 2006 +0000
@@ -58,7 +58,8 @@
 
     OutputList getOutputDescriptors() const;
 
-    FeatureSet process(float **inputBuffers, Vamp::RealTime timestamp);
+    FeatureSet process(const float *const *inputBuffers,
+                       Vamp::RealTime timestamp);
 
     FeatureSet getRemainingFeatures();
 
--- a/examples/ZeroCrossing.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/ZeroCrossing.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -130,7 +130,8 @@
 }
 
 ZeroCrossing::FeatureSet
-ZeroCrossing::process(float **inputBuffers, Vamp::RealTime timestamp)
+ZeroCrossing::process(const float *const *inputBuffers,
+                      Vamp::RealTime timestamp)
 {
     if (m_stepSize == 0) {
 	cerr << "ERROR: ZeroCrossing::process: "
--- a/examples/ZeroCrossing.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/examples/ZeroCrossing.h	Fri Dec 08 17:39:32 2006 +0000
@@ -58,7 +58,8 @@
 
     OutputList getOutputDescriptors() const;
 
-    FeatureSet process(float **inputBuffers, Vamp::RealTime timestamp);
+    FeatureSet process(const float *const *inputBuffers,
+                       Vamp::RealTime timestamp);
 
     FeatureSet getRemainingFeatures();
 
--- a/host/vamp-simple-host.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/host/vamp-simple-host.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -249,7 +249,7 @@
 
     float *filebuf = new float[blockSize * channels];
     float **plugbuf = new float*[channels];
-    for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize];
+    for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
 
     cerr << "Using block size = " << blockSize << ", step size = "
               << stepSize << endl;
@@ -377,11 +377,16 @@
         }
         struct dirent *e = 0;
         while ((e = readdir(d))) {
-            if (!(e->d_type & DT_REG)) continue;
+//            cerr << "reading: " << e->d_name << endl;
+            if (!(e->d_type & DT_REG)) {
+//                cerr << e->d_name << ": not a regular file" << endl;
+                continue;
+            }
             int len = strlen(e->d_name);
             if (len < int(strlen(PLUGIN_SUFFIX) + 2) ||
                 e->d_name[len - strlen(PLUGIN_SUFFIX) - 1] != '.' ||
                 strcmp(e->d_name + len - strlen(PLUGIN_SUFFIX), PLUGIN_SUFFIX)) {
+//                cerr << e->d_name << ": not a library file" << endl;
                 continue;
             }
             char *fp = new char[path[i].length() + len + 3];
@@ -397,7 +402,9 @@
                     const VampPluginDescriptor *descriptor = 0;
                     while ((descriptor = fn(index))) {
                         Vamp::PluginHostAdapter plugin(descriptor, 48000);
-                        cerr << "    [" << char('A' + index) << "] "
+                        char c = char('A' + index);
+                        if (c > 'Z') c = char('a' + (index - 26));
+                        cerr << "    [" << c << "] "
                              << plugin.getDescription()
                              << ", \"" << plugin.getName() << "\""
                              << " [" << plugin.getMaker()
@@ -414,9 +421,13 @@
                         }
                         ++index;
                     }
+                } else {
+//                    cerr << e->d_name << ": no Vamp descriptor function" << endl;
                 }
                 DLCLOSE(handle);
-            }
+            } else {
+                cerr << "\n" << e->d_name << ": unable to load library (" << DLERROR() << ")" << endl;
+            }                
         }
         closedir(d);
     }
@@ -462,7 +473,7 @@
 
     fft(size, false, inbuf, inbuf + size, outbuf, outbuf + size);
 
-    for (size_t i = 0; i < size/2; ++i) {
+    for (size_t i = 0; i <= size/2; ++i) {
         buffer[i * 2] = outbuf[i];
         buffer[i * 2 + 1] = outbuf[i + size];
     }
--- a/vamp-sdk/Plugin.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp-sdk/Plugin.h	Fri Dec 08 17:39:32 2006 +0000
@@ -346,19 +346,21 @@
      *
      * If the plugin's inputDomain is FrequencyDomain, inputBuffers
      * will point to one array of floats per input channel, and each
-     * of these arrays will contain blockSize/2 consecutive pairs of
+     * of these arrays will contain blockSize/2+1 consecutive pairs of
      * real and imaginary component floats corresponding to bins
-     * 0..(blockSize/2-1) of the FFT output.  The timestamp will be
-     * the real time in seconds of the centre of the FFT input window
-     * (i.e. the very first block passed to process might contain the
-     * FFT of half a block of zero samples and the first half-block of
-     * the actual data, with a timestamp of zero).
+     * 0..(blockSize/2) of the FFT output, where bin 0 contains the DC
+     * output and bin blockSize/2 corresponds to the Nyquist output.
+     * The timestamp will be the real time in seconds of the centre of
+     * the FFT input window (i.e. the very first block passed to
+     * process might contain the FFT of half a block of zero samples
+     * and the first half-block of the actual data, with a timestamp
+     * of zero).
      *
      * Return any features that have become available after this
      * process call.  (These do not necessarily have to fall within
      * the process block, except for OneSamplePerStep outputs.)
      */
-    virtual FeatureSet process(float **inputBuffers,
+    virtual FeatureSet process(const float *const *inputBuffers,
 			       RealTime timestamp) = 0;
 
     /**
--- a/vamp-sdk/PluginAdapter.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp-sdk/PluginAdapter.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -423,7 +423,7 @@
 
 VampFeatureList *
 PluginAdapterBase::vampProcess(VampPluginHandle handle,
-                               float **inputBuffers,
+                               const float *const *inputBuffers,
                                int sec,
                                int nsec)
 {
@@ -571,7 +571,7 @@
     
 VampFeatureList *
 PluginAdapterBase::process(Plugin *plugin,
-                           float **inputBuffers,
+                           const float *const *inputBuffers,
                            int sec, int nsec)
 {
 //    std::cerr << "PluginAdapterBase::process" << std::endl;
--- a/vamp-sdk/PluginAdapter.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp-sdk/PluginAdapter.h	Fri Dec 08 17:39:32 2006 +0000
@@ -85,7 +85,7 @@
     static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
 
     static VampFeatureList *vampProcess(VampPluginHandle handle,
-                                        float **inputBuffers,
+                                        const float *const *inputBuffers,
                                         int sec,
                                         int nsec);
 
@@ -99,8 +99,8 @@
     VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
                                              unsigned int i);
     VampFeatureList *process(Plugin *plugin,
-                              float **inputBuffers,
-                              int sec, int nsec);
+                             const float *const *inputBuffers,
+                             int sec, int nsec);
     VampFeatureList *getRemainingFeatures(Plugin *plugin);
     VampFeatureList *convertFeatures(Plugin *plugin,
                                      const Plugin::FeatureSet &features);
@@ -131,7 +131,7 @@
 {
 public:
     PluginAdapter() : PluginAdapterBase() { }
-    ~PluginAdapter() { }
+    virtual ~PluginAdapter() { }
 
 protected:
     Plugin *createPlugin(float inputSampleRate) {
--- a/vamp-sdk/PluginBase.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp-sdk/PluginBase.h	Fri Dec 08 17:39:32 2006 +0000
@@ -63,42 +63,44 @@
     /**
      * Get the computer-usable name of the plugin.  This should be
      * reasonably short and contain no whitespace or punctuation
-     * characters.  It may be shown to the user, but it won't be the
-     * main method for a user to identify a plugin (that will be the
-     * description, below).  This may only contain the characters
-     * [a-zA-Z0-9_].
+     * characters.  It may only contain the characters [a-zA-Z0-9_].
+     * This is the authoritative way for a program to identify a
+     * plugin within a given library.
+     *
+     * This text may be visible to the user, but it should not be the
+     * main text used to identify a plugin to the user (that will be
+     * the description, below).
      */
     virtual std::string getName() const = 0;
 
     /**
-     * Get a human-readable description of the plugin.  This should be
-     * self-contained, as it may be shown to the user in isolation
-     * without also showing the plugin's "name".
+     * Get a human-readable description or title of the plugin.  This
+     * should be brief and self-contained, as it may be used to
+     * identify the plugin to the user in isolation (i.e. without also
+     * showing the plugin's "name").
      */
     virtual std::string getDescription() const = 0;
     
     /**
      * Get the name of the author or vendor of the plugin in
-     * human-readable form.
+     * human-readable form.  This should be a short identifying text,
+     * as it may be used to label plugins from the same source in a
+     * menu or similar.
      */
     virtual std::string getMaker() const = 0;
 
     /**
+     * Get the copyright statement or licensing summary for the
+     * plugin.  This can be an informative text, without the same
+     * presentation constraints as mentioned for getMaker above.
+     */
+    virtual std::string getCopyright() const = 0;
+
+    /**
      * Get the version number of the plugin.
      */
     virtual int getPluginVersion() const = 0;
 
-    /**
-     * Get the copyright statement or licensing summary of the plugin.
-     */
-    virtual std::string getCopyright() const = 0;
-
-    /**
-     * Get the type of plugin (e.g. DSSI, etc).  This is likely to be
-     * implemented by the immediate subclass, not by actual plugins.
-     */
-    virtual std::string getType() const = 0;
-
 
     struct ParameterDescriptor
     {
@@ -204,6 +206,13 @@
      * available programs, do nothing.)
      */
     virtual void selectProgram(std::string) { }
+
+    /**
+     * Get the type of plugin.  This is to be implemented by the
+     * immediate subclass, not by actual plugins.  Do not attempt to
+     * implement this in plugin code.
+     */
+    virtual std::string getType() const = 0;
 };
 
 }
--- a/vamp-sdk/PluginHostAdapter.cpp	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp-sdk/PluginHostAdapter.cpp	Fri Dec 08 17:39:32 2006 +0000
@@ -335,8 +335,8 @@
 }
 
 PluginHostAdapter::FeatureSet
-PluginHostAdapter::process(float **inputBuffers,
-                                            RealTime timestamp)
+PluginHostAdapter::process(const float *const *inputBuffers,
+                           RealTime timestamp)
 {
     FeatureSet fs;
     if (!m_handle) return fs;
--- a/vamp-sdk/PluginHostAdapter.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp-sdk/PluginHostAdapter.h	Fri Dec 08 17:39:32 2006 +0000
@@ -81,7 +81,7 @@
 
     OutputList getOutputDescriptors() const;
 
-    FeatureSet process(float **inputBuffers, RealTime timestamp);
+    FeatureSet process(const float *const *inputBuffers, RealTime timestamp);
 
     FeatureSet getRemainingFeatures();
 
--- a/vamp/vamp.h	Thu Nov 30 15:00:17 2006 +0000
+++ b/vamp/vamp.h	Fri Dec 08 17:39:32 2006 +0000
@@ -285,7 +285,7 @@
         releaseFeatureSet for this feature set. Host must call
         releaseFeatureSet after use. */
     VampFeatureList *(*process)(VampPluginHandle,
-                                float **inputBuffers,
+                                const float *const *inputBuffers,
                                 int sec,
                                 int nsec);