changeset 5:7fc28f7a935a

...
author cannam
date Mon, 06 Nov 2006 20:12:38 +0000
parents f0e9092bd3e4
children b046af03c719
files audioio/BufferingAudioCallbackRecordTarget.cpp audioio/BufferingAudioCallbackRecordTarget.h host/Processor.cpp host/Processor.h test.xml
diffstat 5 files changed, 129 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/audioio/BufferingAudioCallbackRecordTarget.cpp	Mon Nov 06 14:41:46 2006 +0000
+++ b/audioio/BufferingAudioCallbackRecordTarget.cpp	Mon Nov 06 20:12:38 2006 +0000
@@ -26,10 +26,14 @@
 BufferingAudioCallbackRecordTarget::putSamples(size_t nframes, float **samples)
 {
     for (size_t c = 0; c < getChannelCount(); ++c) {
+        size_t written = nframes;
         if (samples[c]) {
-            m_buffers[c]->write(samples[c], nframes);
+            written = m_buffers[c]->write(samples[c], nframes);
         } else {
-            m_buffers[c]->zero(nframes);
+            written = m_buffers[c]->zero(nframes);
+        }
+        if (written < nframes) {
+            std::cerr << "WARNING: BufferingAudioCallbackRecordTarget::putSamples: Buffer overflow: wrote " << written << " of " << nframes << " samples on channel " << c << std::endl;
         }
     }
 }
@@ -66,3 +70,11 @@
     return m_buffers[channel]->skip(nframes, reader);
 }
 
+size_t
+BufferingAudioCallbackRecordTarget::skipAllSamples(size_t channel,
+                                                   int reader)
+{
+    return m_buffers[channel]->skip(m_buffers[channel]->getReadSpace(reader),
+                                    reader);
+}
+
--- a/audioio/BufferingAudioCallbackRecordTarget.h	Mon Nov 06 14:41:46 2006 +0000
+++ b/audioio/BufferingAudioCallbackRecordTarget.h	Mon Nov 06 20:12:38 2006 +0000
@@ -33,6 +33,7 @@
     virtual size_t peekSamples(size_t channel, size_t nframes, float *samples,
                                int reader = 0);
     virtual size_t skipSamples(size_t channel, size_t nframes, int reader = 0);
+    virtual size_t skipAllSamples(size_t channel, int reader = 0);
     
     virtual void setInputLevels(float, float) { }
 
--- a/host/Processor.cpp	Mon Nov 06 14:41:46 2006 +0000
+++ b/host/Processor.cpp	Mon Nov 06 20:12:38 2006 +0000
@@ -18,11 +18,13 @@
     m_exiting(false),
     m_audioRecordTarget(audioRecordTarget),
     m_nextNumber(1),
-    m_nextReader(0),
     m_havePlugins(false),
     m_minBlockSize(0),
     m_maxBlockSize(0)
 {
+    for (int i = 0; i < MAX_DISTINCT_STEP_SIZES; ++i) {
+        m_unusedReaders.insert(i);
+    }
 }
 
 Processor::~Processor()
@@ -58,6 +60,16 @@
         } else {
             msleep(50);
         }
+
+        m_mutex.lock();
+        for (ReaderSet::iterator i = m_unusedReaders.begin();
+             i != m_unusedReaders.end(); ++i) {
+            size_t ch = m_audioRecordTarget->getChannelCount();
+            for (size_t c = 0; c < ch; ++c) {
+                m_audioRecordTarget->skipAllSamples(c, *i);
+            }
+        }
+        m_mutex.unlock();
     }
 }
 
@@ -126,8 +138,14 @@
 #endif
 
             for (size_t c = 0; c < ch; ++c) {
-                m_audioRecordTarget->peekSamples(c, maxBlock, buffers[c], reader);
-                m_audioRecordTarget->skipSamples(c, step, reader);
+                size_t got = m_audioRecordTarget->peekSamples(c, maxBlock, buffers[c], reader);
+                if (got < maxBlock) {
+                    cerr << "ERROR: Requested " << maxBlock << " samples on channel " << c << " reader " << reader << ", only got " << got << endl;
+                }
+                size_t skipped = m_audioRecordTarget->skipSamples(c, step, reader);
+                if (skipped < step) {
+                    cerr << "ERROR: Requested skip of " << step << " samples on channel " << c << " reader " << reader << ", only skipped " << skipped << endl;
+                }
             }
 
             for (BlockSizePluginMap::iterator j = i->second.begin();
@@ -175,10 +193,29 @@
                             float *tmp[10];
                             for (size_t c = 0; c < ch; ++c) {
                                 tmp[c] = buffers[c] + off;
-                                fs = plugin->process(tmp, timestamp);
+                            }
+                            fs = plugin->process(tmp, timestamp);
+                        }
+            
+                        int pluginIndex = m_pluginRMap[plugin];
+
+                        if (fs.empty()) {
+                            for (OutputStateMap::iterator oi = 
+                                     m_pluginStates[pluginIndex].begin();
+                                 oi != m_pluginStates[pluginIndex].end(); ++oi) {
+                                int output = oi->first;
+                                OutputState currentState = oi->second;
+                            
+                                Vamp::RealTime rt =
+                                    Vamp::RealTime::frame2RealTime(frame[reader], sr);
+
+                                bool changed = currentState.present;
+                                Vamp::RealTime gap = rt - currentState.laststamp;
+                                m_pluginStates[pluginIndex][output] =
+                                    OutputState(false, changed, currentState.value, currentState.laststamp, currentState.gap);
                             }
                         }
-            
+
                         for (Vamp::Plugin::FeatureSet::iterator fi = fs.begin();
                              fi != fs.end(); ++fi) {
 
@@ -201,17 +238,14 @@
 
                             Vamp::Plugin::FeatureList fl(fi->second);
                             
-                            //!!! need rmap set up
-                            int pluginIndex = m_pluginRMap[plugin];
-
                             OutputState currentState = 
                                 m_pluginStates[pluginIndex][output];
-
+                            
                             if (fl.empty()) {
                                 bool changed = currentState.present;
                                 Vamp::RealTime gap = rt - currentState.laststamp;
                                 m_pluginStates[pluginIndex][output] =
-                                    OutputState(false, changed, currentState.value, rt, gap);
+                                    OutputState(false, changed, currentState.value, currentState.laststamp, currentState.gap);
                             } else {
 
                                 if (fl[0].hasTimestamp) {
@@ -221,8 +255,12 @@
                                 if (!fl[0].values.empty()) {
                                     value = fl[0].values[0];
                                 }
-                                bool changed = (currentState.value != value);
+                                bool changed =
+                                    (!currentState.present ||
+                                     (fabsf(currentState.value - value) >
+                                      0.000001));
                                 Vamp::RealTime gap = rt - currentState.laststamp;
+                                std::cerr << "gap = " << gap << std::endl;
                                 m_pluginStates[pluginIndex][output] =
                                     OutputState(true, changed, value, rt, gap);
                             }
@@ -295,12 +333,14 @@
     }
 
     if (m_stepSizeReaderMap.find(step) == m_stepSizeReaderMap.end()) {
-        if (m_nextReader == MAX_DISTINCT_STEP_SIZES) {
+        if (m_unusedReaders.empty()) {
             cerr << "ERROR: Processor::addPlugin: Run out of distinct step size slots: increase MAX_DISTINCT_STEP_SIZES and recompile" << endl;
             delete plugin;
             return 0;
         }
-        m_stepSizeReaderMap[step] = m_nextReader++;
+        int reader = *m_unusedReaders.begin();
+        m_unusedReaders.erase(reader);
+        m_stepSizeReaderMap[step] = reader;
     }
 
     size_t ch = m_audioRecordTarget->getChannelCount();
@@ -315,6 +355,10 @@
     if (!m_havePlugins || block < m_minBlockSize) m_minBlockSize = block;
     if (!m_havePlugins || block > m_maxBlockSize) m_maxBlockSize = block;
 
+    std::cerr << "initialised plugin \"" << pluginId.toStdString() 
+              << "\" with step \"" << step << "\" block \"" << block << "\""
+              << std::endl;
+
     int number = m_nextNumber++;
     m_plugins[number] = plugin;
     m_pluginRMap[plugin] = number;
@@ -357,11 +401,7 @@
                         
                         m_processingMap.erase(i->first);
                         m_stepSizeReaderMap.erase(i->first);
-                        
-                        //!!! need to make it possible to use that
-                        //reader again, but we can't without having a
-                        //reader bitset rather than a next reader
-                        //count
+                        m_unusedReaders.insert(i->first);
                     }
                 }
                 
@@ -401,11 +441,51 @@
 
         OutputState state = m_pluginStates[pluginIndex][outputNumber];
         
-        //!!!
-        if (condition == Rule::GreaterThan) {
-            if (state.value > argument) {
-                std::cerr << "FIRING RULE: " << state.value << " > " << argument << std::endl;
-            }
+#ifdef DEBUG_RUN_PROCESSOR
+        std::cerr << "Present = " << state.present << ", changed = " << state.changed << ", value = " << state.value << std::endl;
+#endif
+
+        if (!state.changed) continue;
+
+        bool fire = false;
+
+        switch (condition) {
+
+        case Rule::GreaterThan:
+            fire = (state.value > argument);
+            break;
+
+        case Rule::LessThan:
+            fire = (state.value < argument);
+            break;
+
+        case Rule::EqualTo:
+            fire = fabsf(state.value - argument) < 0.000001;
+            break;
+
+        case Rule::NotEqualTo:
+            fire = fabsf(state.value - argument) > 0.000001;
+            break;
+
+        case Rule::Present:
+            fire = state.present;
+            break;
+
+        case Rule::Changed:
+            fire = true;
+            break;
+
+        case Rule::GapGreaterThan:
+            fire = (state.gap > Vamp::RealTime::fromSeconds(argument));
+            break;
+
+        case Rule::GapLessThan:
+            fire = (state.gap < Vamp::RealTime::fromSeconds(argument));
+            break;
+        }
+
+        if (fire) {
+            std::cerr << "FIRING RULE: " << image.toStdString() << "!" << std::endl;
         }
     }
 
@@ -415,6 +495,10 @@
 void
 printFeatures(int plugno, int frame, int sr, int output, Vamp::Plugin::FeatureSet &features)
 {
+//    return;//!!!
+
+    if (output > 0) return;//!!!
+
     for (unsigned int i = 0; i < features[output].size(); ++i) {
         Vamp::RealTime rt = Vamp::RealTime::frame2RealTime(frame, sr);
         if (features[output][i].hasTimestamp) {
--- a/host/Processor.h	Mon Nov 06 14:41:46 2006 +0000
+++ b/host/Processor.h	Mon Nov 06 20:12:38 2006 +0000
@@ -52,8 +52,9 @@
 
     // A map from step size to ring buffer reader number
     typedef std::map<size_t, int> StepSizeReaderMap;
+    typedef std::set<int> ReaderSet;
     StepSizeReaderMap m_stepSizeReaderMap;
-    int m_nextReader;
+    ReaderSet m_unusedReaders;
 
     // Map from rule to image name
     typedef std::multimap<Rule, QString> RuleImageMap;
@@ -73,7 +74,8 @@
     };
 
     // Map from plugin index to output index to state
-    typedef std::map<int, std::map<int, OutputState> > PluginStateMap;
+    typedef std::map<int, OutputState> OutputStateMap;
+    typedef std::map<int, OutputStateMap> PluginStateMap;
     PluginStateMap m_pluginStates;
 
     bool m_havePlugins;
--- a/test.xml	Mon Nov 06 14:41:46 2006 +0000
+++ b/test.xml	Mon Nov 06 20:12:38 2006 +0000
@@ -1,9 +1,10 @@
 <vlh>
 <plugins>
   <plugin index="1" id="vamp:vamp-aubio:aubiotempo"/>
-  <plugin index="2" id="vamp:vamp-example-plugins:zerocrossing"/>
+<!--  <plugin index="2" id="vamp:vamp-example-plugins:zerocrossing"/> -->
 </plugins>
 <rules>
-  <outputRule pluginIndex="2" condition="GreaterThan" argument="120" action="image" image="blah"/>
+<outputRule pluginIndex="1" condition="GapLessThan" argument="0.5" action="image" image="fast"/>
+<outputRule pluginIndex="1" outputNumber="0" condition="Present" action="image" image="ping"/>
 </rules>
 </vlh>