changeset 318:2ed36547e1bf

Patch from Dan Stowell to permit vamp-simple-host to read data of unknown length (for streaming input)
author Chris Cannam
date Thu, 18 Aug 2011 12:21:30 +0100
parents 5cb298435765
children 7920b9519fd9
files host/vamp-simple-host.cpp
diffstat 1 files changed, 38 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/host/vamp-simple-host.cpp	Tue Jun 21 15:40:50 2011 +0100
+++ b/host/vamp-simple-host.cpp	Thu Aug 18 12:21:30 2011 +0100
@@ -276,9 +276,9 @@
 
     sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo);
     if (!sndfile) {
-	cerr << myname << ": ERROR: Failed to open input file \""
+        cerr << myname << ": ERROR: Failed to open input file \""
              << wavname << "\": " << sf_strerror(sndfile) << endl;
-	return 1;
+        return 1;
     }
 
     ofstream *out = 0;
@@ -339,6 +339,9 @@
         }
         cerr << blockSize << endl;
     }
+    int overlapSize = blockSize - stepSize;
+    sf_count_t currentStep = 0;
+    int finalStepsRemaining = max(1, (blockSize / stepSize) - 1); // at end of file, this many part-silent frames needed after we hit EOF
 
     int channels = sfinfo.channels;
 
@@ -369,7 +372,7 @@
     RealTime adjustment = RealTime::zeroTime;
 
     if (outputs.empty()) {
-	cerr << "ERROR: Plugin has no outputs!" << endl;
+        cerr << "ERROR: Plugin has no outputs!" << endl;
         goto done;
     }
 
@@ -413,19 +416,28 @@
             wrapper->getWrapper<PluginInputDomainAdapter>();
         if (ida) adjustment = ida->getTimestampAdjustment();
     }
-
-    for (sf_count_t i = 0; i < sfinfo.frames; i += stepSize) {
+    
+    // Here we iterate over the frames, avoiding asking the numframes in case it's streaming input.
+    do {
 
         int count;
 
-        if (sf_seek(sndfile, i, SEEK_SET) < 0) {
-            cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl;
-            break;
-        }
-        
-        if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
-            cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
-            break;
+        if ((blockSize==stepSize) || (currentStep==0)) {
+            // read a full fresh block
+            if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
+                cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
+                break;
+            }
+            if (count != blockSize) --finalStepsRemaining;
+        } else {
+            //  otherwise shunt the existing data down and read the remainder.
+            memmove(filebuf, filebuf + (stepSize * channels), overlapSize * channels * sizeof(float));
+            if ((count = sf_readf_float(sndfile, filebuf + (overlapSize * channels), stepSize)) < 0) {
+                cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
+                break;
+            }
+            if (count != stepSize) --finalStepsRemaining;
+            count += overlapSize;
         }
 
         for (int c = 0; c < channels; ++c) {
@@ -440,22 +452,28 @@
             }
         }
 
-        rt = RealTime::frame2RealTime(i, sfinfo.samplerate);
+        rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
 
         printFeatures
             (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
              sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
              out, useFrames);
 
-        int pp = progress;
-        progress = lrintf((float(i) / sfinfo.frames) * 100.f);
-        if (progress != pp && out) {
-            cerr << "\r" << progress << "%";
+        if (sfinfo.frames > 0){
+            int pp = progress;
+            progress = lrintf((float(currentStep * stepSize) / sfinfo.frames) * 100.f);
+            if (progress != pp && out) {
+                cerr << "\r" << progress << "%";
+            }
         }
-    }
+
+        ++currentStep;
+
+    } while (finalStepsRemaining > 0);
+
     if (out) cerr << "\rDone" << endl;
 
-    rt = RealTime::frame2RealTime(sfinfo.frames, sfinfo.samplerate);
+    rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
 
     printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
                   sfinfo.samplerate, outputNo,