changeset 134:c1dce0b033cb

* Permit '-' as well as the other characters in identifiers (existing plugins were already using this character, it's really the documentation that was at fault) * Fix failure to return output descriptors properly from PluginBufferingAdapter * Fix incorrect sample rate in output descriptors for certain sample types from PluginBufferingAdapter * Fix incorrect timestamping on features returned from PluginBufferingAdapter (rounding error)
author cannam
date Thu, 24 Apr 2008 10:27:02 +0000
parents 92ca8e401044
children 6bffd86a103d
files vamp-sdk/Plugin.h vamp-sdk/PluginBase.h vamp-sdk/hostext/PluginBufferingAdapter.cpp
diffstat 3 files changed, 25 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/vamp-sdk/Plugin.h	Thu Mar 20 13:22:02 2008 +0000
+++ b/vamp-sdk/Plugin.h	Thu Apr 24 10:27:02 2008 +0000
@@ -200,7 +200,7 @@
 	/**
 	 * The name of the output, in computer-usable form.  Should be
 	 * reasonably short and without whitespace or punctuation, using
-         * the characters [a-zA-Z0-9_] only.
+         * the characters [a-zA-Z0-9_-] only.
          * Example: "zero_crossing_count"
 	 */
 	std::string identifier;
--- a/vamp-sdk/PluginBase.h	Thu Mar 20 13:22:02 2008 +0000
+++ b/vamp-sdk/PluginBase.h	Thu Apr 24 10:27:02 2008 +0000
@@ -69,7 +69,7 @@
     /**
      * Get the computer-usable name of the plugin.  This should be
      * reasonably short and contain no whitespace or punctuation
-     * characters.  It 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.
      *
@@ -127,7 +127,7 @@
 	/**
 	 * The name of the parameter, in computer-usable form.  Should
 	 * be reasonably short, and may only contain the characters
-	 * [a-zA-Z0-9_].
+	 * [a-zA-Z0-9_-].
 	 */
 	std::string identifier;
 
--- a/vamp-sdk/hostext/PluginBufferingAdapter.cpp	Thu Mar 20 13:22:02 2008 +0000
+++ b/vamp-sdk/hostext/PluginBufferingAdapter.cpp	Thu Apr 24 10:27:02 2008 +0000
@@ -227,12 +227,12 @@
     vector<RingBuffer *> m_queue;
     float **m_buffers;
     float m_inputSampleRate;
-    RealTime m_timestamp;
+    long m_frame;
     bool m_unrun;
     mutable OutputList m_outputs;
     mutable std::map<int, bool> m_rewriteOutputTimes;
 		
-    void processBlock(FeatureSet& allFeatureSets, RealTime timestamp);
+    void processBlock(FeatureSet& allFeatureSets);
 };
 		
 PluginBufferingAdapter::PluginBufferingAdapter(Plugin *plugin) :
@@ -287,7 +287,7 @@
     m_queue(0),
     m_buffers(0),
     m_inputSampleRate(inputSampleRate),
-    m_timestamp(RealTime::zeroTime),
+    m_frame(0),
     m_unrun(true)
 {
     (void)getOutputDescriptors(); // set up m_outputs and m_rewriteOutputTimes
@@ -370,7 +370,7 @@
         m_outputs = m_plugin->getOutputDescriptors();
     }
 
-    PluginBufferingAdapter::OutputList outs;
+    PluginBufferingAdapter::OutputList outs = m_outputs;
 
     for (size_t i = 0; i < outs.size(); ++i) {
 
@@ -378,13 +378,13 @@
 
         case OutputDescriptor::OneSamplePerStep:
             outs[i].sampleType = OutputDescriptor::FixedSampleRate;
-            outs[i].sampleRate = 1.f / m_stepSize;
+            outs[i].sampleRate = (1.f / m_inputSampleRate) * m_stepSize;
             m_rewriteOutputTimes[i] = true;
             break;
             
         case OutputDescriptor::FixedSampleRate:
             if (outs[i].sampleRate == 0.f) {
-                outs[i].sampleRate = 1.f / m_stepSize;
+                outs[i].sampleRate = (1.f / m_inputSampleRate) * m_stepSize;
             }
             // We actually only need to rewrite output times for
             // features that don't have timestamps already, but we
@@ -405,7 +405,7 @@
 void
 PluginBufferingAdapter::Impl::reset()
 {
-    m_timestamp = RealTime::zeroTime;
+    m_frame = 0;
     m_unrun = true;
 
     for (size_t i = 0; i < m_queue.size(); ++i) {
@@ -420,7 +420,8 @@
     FeatureSet allFeatureSets;
 
     if (m_unrun) {
-        m_timestamp = timestamp;
+        m_frame = RealTime::realTime2Frame(timestamp,
+                                           int(m_inputSampleRate + 0.5));
         m_unrun = false;
     }
 			
@@ -441,7 +442,7 @@
     // process as much as we can
 
     while (m_queue[0]->getReadSpace() >= int(m_blockSize)) {
-        processBlock(allFeatureSets, timestamp);
+        processBlock(allFeatureSets);
     }	
     
     return allFeatureSets;
@@ -454,7 +455,7 @@
     
     // process remaining samples in queue
     while (m_queue[0]->getReadSpace() >= int(m_blockSize)) {
-        processBlock(allFeatureSets, m_timestamp);
+        processBlock(allFeatureSets);
     }
     
     // pad any last samples remaining and process
@@ -462,7 +463,7 @@
         for (size_t i = 0; i < m_channels; ++i) {
             m_queue[i]->zero(m_blockSize - m_queue[i]->getReadSpace());
         }
-        processBlock(allFeatureSets, m_timestamp);
+        processBlock(allFeatureSets);
     }			
     
     // get remaining features			
@@ -481,14 +482,17 @@
 }
     
 void
-PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets,
-                                           RealTime timestamp)
+PluginBufferingAdapter::Impl::processBlock(FeatureSet& allFeatureSets)
 {
     for (size_t i = 0; i < m_channels; ++i) {
         m_queue[i]->peek(m_buffers[i], m_blockSize);
     }
 
-    FeatureSet featureSet = m_plugin->process(m_buffers, m_timestamp);
+    long frame = m_frame;
+    RealTime timestamp = RealTime::frame2RealTime
+        (frame, int(m_inputSampleRate + 0.5));
+
+    FeatureSet featureSet = m_plugin->process(m_buffers, timestamp);
     
     for (FeatureSet::iterator iter = featureSet.begin();
          iter != featureSet.end(); ++iter) {
@@ -497,8 +501,6 @@
 
         if (m_rewriteOutputTimes[outputNo]) {
             
-            // Make sure the timestamp is always set
-	
             FeatureList featureList = iter->second;
 	
             for (size_t i = 0; i < featureList.size(); ++i) {
@@ -507,14 +509,14 @@
 
                 case OutputDescriptor::OneSamplePerStep:
                     // use our internal timestamp, always
-                    featureList[i].timestamp = m_timestamp;
+                    featureList[i].timestamp = timestamp;
                     featureList[i].hasTimestamp = true;
                     break;
 
                 case OutputDescriptor::FixedSampleRate:
                     // use our internal timestamp if feature lacks one
                     if (!featureList[i].hasTimestamp) {
-                        featureList[i].timestamp = m_timestamp;
+                        featureList[i].timestamp = timestamp;
                         featureList[i].hasTimestamp = true;
                     }
                     break;
@@ -541,12 +543,8 @@
         m_queue[i]->skip(m_stepSize);
     }
     
-    // fake up the timestamp each time we step forward
-
-    long frame = RealTime::realTime2Frame(m_timestamp,
-                                          int(m_inputSampleRate + 0.5));
-    m_timestamp = RealTime::frame2RealTime(frame + m_stepSize,
-                                           int(m_inputSampleRate + 0.5));
+    // increment internal frame counter each time we step forward
+    m_frame += m_stepSize;
 }
 
 }