changeset 96:5ceb37190bd9

Alignment is now right in inverse transform, but the padding at end is still wrong
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 09 May 2014 17:43:00 +0100
parents 8d04787ca7dc
children e599e0b13388
files cpp-qm-dsp/CQInverse.cpp cpp-qm-dsp/CQInverse.h cpp-qm-dsp/processfile.cpp
diffstat 3 files changed, 67 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/cpp-qm-dsp/CQInverse.cpp	Fri May 09 15:36:23 2014 +0100
+++ b/cpp-qm-dsp/CQInverse.cpp	Fri May 09 17:43:00 2014 +0100
@@ -116,21 +116,46 @@
         m_upsamplers.push_back(r);
     }
 
-    m_bigBlockSize = m_p.fftSize * pow(2, m_octaves - 1);
-
-    //!!! review this later for the hops-dropped stuff
-    int maxLatency = 0;
+    // additionally we will have fftHop latency at individual octave
+    // rate (before upsampling) for the overlap-add in each octave
     for (int i = 0; i < m_octaves; ++i) {
-	if (latencies[i] > maxLatency) maxLatency = latencies[i];
+        latencies[i] += m_p.fftHop * pow(2, i);
     }
 
-    m_outputLatency = maxLatency; //!!! for now
+    // Now reverse the drop adjustment made in ConstantQ to align the
+    // atom centres across different octaves (but this time at output
+    // sample rate)
+
+    int emptyHops = m_p.firstCentre / m_p.atomSpacing;
+
+    vector<int> pushes;
+    for (int i = 0; i < m_octaves; ++i) {
+	int factor = pow(2, i);
+	int pushHops = emptyHops * pow(2, m_octaves - i - 1) - emptyHops;
+	int push = ((pushHops * m_p.fftHop) * factor) / m_p.atomsPerFrame;
+	pushes.push_back(push);
+    }
+
+    int bigBlockSize = m_p.fftSize * pow(2, m_octaves - 1);
+    int maxLatLessPush = 0;
+    for (int i = 0; i < m_octaves; ++i) {
+	int latLessPush = bigBlockSize + latencies[i] - pushes[i];
+	if (latLessPush > maxLatLessPush) maxLatLessPush = latLessPush;
+    }
+
+    int totalLatency = maxLatLessPush;
+
+    m_outputLatency = totalLatency + m_p.firstCentre * pow(2, m_octaves-1);
 
     for (int i = 0; i < m_octaves; ++i) {
+
 	// Calculate the difference between the total latency applied
 	// across all octaves, and the existing latency due to the
-	// upsampler for this octave
-        m_buffers.push_back(RealSequence(m_outputLatency - latencies[i], 0.0));
+	// upsampler for this octave.
+
+        int latencyPadding = totalLatency - latencies[i] + pushes[i];
+
+        m_buffers.push_back(RealSequence(latencyPadding, 0.0));
     }
 
     for (int i = 0; i < m_octaves; ++i) {
@@ -156,8 +181,6 @@
         return drawFromBuffers();
     }
 
-    cerr << "process: given " << widthProvided << " cols" << endl;
-
     int blockWidth = m_p.atomsPerFrame * int(pow(2, m_octaves - 1));
 
     if (widthProvided % blockWidth != 0) {
@@ -243,15 +266,18 @@
                                     m_buffers[i].end());
     }
 
-    cerr << "process: returning " << available << endl;
-
     return result;
 }
 
 CQInverse::RealSequence
 CQInverse::getRemainingOutput()
 {
-    //!!! for now -- may have to prompt the resamplers?
+    for (int i = 0; i < (m_p.fftSize - m_p.fftHop) / m_p.fftHop; ++i) {
+        for (int j = 0; j < m_octaves; ++j) {
+            overlapAddAndResample(j, RealSequence(m_olaBufs[j].size(), 0));
+        }
+    }
+
     return drawFromBuffers();
 }
 
--- a/cpp-qm-dsp/CQInverse.h	Fri May 09 15:36:23 2014 +0100
+++ b/cpp-qm-dsp/CQInverse.h	Fri May 09 17:43:00 2014 +0100
@@ -72,7 +72,6 @@
 
     CQKernel *m_kernel;
     CQKernel::Properties m_p;
-    int m_bigBlockSize;
 
     std::vector<Resampler *> m_upsamplers;
     std::vector<RealSequence> m_buffers;
--- a/cpp-qm-dsp/processfile.cpp	Fri May 09 15:36:23 2014 +0100
+++ b/cpp-qm-dsp/processfile.cpp	Fri May 09 17:43:00 2014 +0100
@@ -12,6 +12,9 @@
 
 #include <cstring>
 
+#include <unistd.h>
+#include <sys/time.h>
+
 int main(int argc, char **argv)
 {
     if (argc != 3) {
@@ -48,7 +51,7 @@
 	     << sf_strerror(sndfileOut) << endl;
 	return 1;
     }
-    
+
     int ibs = 1024;
     int channels = sfinfo.channels;
     float *fbuf = new float[channels * ibs];
@@ -65,6 +68,12 @@
     int outframe = 0;
     int latency = cq.getLatency() + cqi.getLatency();
 
+    cerr << "forward latency = " << cq.getLatency() << ", inverse latency = " 
+	 << cqi.getLatency() << ", total = " << latency << endl;
+
+    timeval tv;
+    (void)gettimeofday(&tv, 0);
+
     while (inframe < sfinfo.frames) {
 
         int count = -1;
@@ -111,9 +120,27 @@
     sf_writef_double(sndfileOut, r1.data(), r1.size());
     sf_writef_double(sndfileOut, r2.data(), r2.size());
 
+    outframe += r1.size();
+    outframe += r2.size();
+
     sf_close(sndfile);
     sf_close(sndfileOut);
 
+    cerr << "in: " << inframe << ", out: " << outframe - latency << endl;
+
+    timeval etv;
+    (void)gettimeofday(&etv, 0);
+        
+    etv.tv_sec -= tv.tv_sec;
+    if (etv.tv_usec < tv.tv_usec) {
+	etv.tv_usec += 1000000;
+	etv.tv_sec -= 1;
+    }
+    etv.tv_usec -= tv.tv_usec;
+        
+    double sec = double(etv.tv_sec) + (double(etv.tv_usec) / 1000000.0);
+    cerr << "elapsed time (not counting init): " << sec << " sec, frames/sec at input: " << inframe/sec << endl;
+
     return 0;
 }