changeset 92:5a3163eff37a

A bit more on inverse
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 09 May 2014 11:15:56 +0100
parents 51f5f0deef2f
children 908be1d06bd2
files cpp-qm-dsp/CQInverse.cpp cpp-qm-dsp/CQInverse.h cpp-qm-dsp/ConstantQ.cpp cpp-qm-dsp/ConstantQ.h
diffstat 4 files changed, 76 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/cpp-qm-dsp/CQInverse.cpp	Fri May 09 10:56:23 2014 +0100
+++ b/cpp-qm-dsp/CQInverse.cpp	Fri May 09 11:15:56 2014 +0100
@@ -149,10 +149,18 @@
     // implementation.
 
     int blockWidth = m_p.atomsPerFrame * int(pow(2, m_octaves - 1));
-    if (block.size() % blockWidth != 0) {
+
+    int widthProvided = block.size();
+
+    if (widthProvided % blockWidth != 0) {
+        cerr << "ERROR: CQInverse::process: Input block size ("
+             << widthProvided
+             << ") must be a multiple of processing block width "
+             << "(atoms-per-frame * 2^(octaves-1) = "
+             << m_p.atomsPerFrame << " * 2^(" << m_octaves << "-1) = "
+             << blockWidth << ")" << endl;
         throw std::invalid_argument
-            ("Input block size must be a multiple of processing block width "
-             "(atoms-per-frame * 2^(octaves-1))");
+            ("Input block size must be a multiple of processing block width");
     }
 
     // Procedure:
@@ -174,6 +182,62 @@
     // 5. Resample each octave's overlap-add stream to the original
     // rate, and sum.
     
+    // We will, for now, do all but the last step in sequence, one
+    // octave at a time, and push the results to m_buffers for summing
+    // and return.
+
+    for (int i = 0; i < m_octaves; ++i) {
+        
+        ComplexBlock oct;
+
+        for (int j = 0; j < widthProvided; ++j) {
+            int h = block[j].size();
+            if (h < m_binsPerOctave * (i+1)) {
+                continue;
+            }
+            ComplexColumn col(block[j].begin() + m_binsPerOctave * i,
+                              block[j].begin() + m_binsPerOctave * (i+1));
+            oct.push_back(col);
+        }
+
+        processOctave(i, oct);
+    }
+            
+#error need to return something
 }
 
+void
+CQInverse::processOctave(int octave, const ComplexBlock &columns)
+{
+    // 2. Group each octave list by atomsPerFrame columns at a time,
+    // and stack these so as to achieve a list, for each octave, of
+    // taller columns of height binsPerOctave * atomsPerFrame
 
+    int ncols = columns.size();
+
+    if (ncols % m_p.atomsPerFrame != 0) {
+        cerr << "ERROR: CQInverse::process: Number of columns ("
+             << ncols
+             << ") in octave " << octave
+             << " must be a multiple of atoms-per-frame ("
+             << m_p.atomsPerFrame << ")" << endl;
+        throw std::invalid_argument
+            ("Columns in octave must be a multiple of atoms per frame");
+    }
+
+    ComplexBlock reshaped;
+    for (int i = 0; i < ncols; i += m_p.atomsPerFrame) {
+        ComplexColumn tallcol;
+        for (int b = 0; b < m_binsPerOctave; ++b) {
+            for (int a = 0; a < m_p.atomsPerFrame; ++a) {
+                tallcol.push_back(columns[i + a][b]);
+            }
+        }
+        reshaped.push_back(tallcol);
+    }
+
+    
+
+}
+
+
--- a/cpp-qm-dsp/CQInverse.h	Fri May 09 10:56:23 2014 +0100
+++ b/cpp-qm-dsp/CQInverse.h	Fri May 09 11:15:56 2014 +0100
@@ -75,13 +75,14 @@
     int m_bigBlockSize;
 
     std::vector<Resampler *> m_upsamplers;
-    std::vector<std::vector<double> > m_buffers;
+    std::vector<RealSequence> m_buffers;
     
     int m_outputLatency;
 
     FFTReal *m_fft;
     
     void initialise();
+    void processOctave(int octave, const ComplexBlock &block);
 };
 
 #endif
--- a/cpp-qm-dsp/ConstantQ.cpp	Fri May 09 10:56:23 2014 +0100
+++ b/cpp-qm-dsp/ConstantQ.cpp	Fri May 09 11:15:56 2014 +0100
@@ -205,7 +205,7 @@
 		   + m_bigBlockSize) / factor;
 
         m_buffers.push_back
-            (vector<double>(int(round(octaveLatency)), 0.0));
+            (RealSequence(int(round(octaveLatency)), 0.0));
     }
 
     m_fft = new FFTReal(m_p.fftSize);
@@ -217,7 +217,7 @@
     m_buffers[0].insert(m_buffers[0].end(), td.begin(), td.end());
 
     for (int i = 1; i < m_octaves; ++i) {
-        vector<double> dec = m_decimators[i]->process(td.data(), td.size());
+        RealSequence dec = m_decimators[i]->process(td.data(), td.size());
         m_buffers[i].insert(m_buffers[i].end(), dec.begin(), dec.end());
     }
 
@@ -282,19 +282,19 @@
 {
     // Same as padding added at start, though rounded up
     int pad = ceil(double(m_outputLatency) / m_bigBlockSize) * m_bigBlockSize;
-    vector<double> zeros(pad, 0.0);
+    RealSequence zeros(pad, 0.0);
     return process(zeros);
 }
 
 ConstantQ::ComplexBlock
 ConstantQ::processOctaveBlock(int octave)
 {
-    vector<double> ro(m_p.fftSize, 0.0);
-    vector<double> io(m_p.fftSize, 0.0);
+    RealSequence ro(m_p.fftSize, 0.0);
+    RealSequence io(m_p.fftSize, 0.0);
 
     m_fft->forward(m_buffers[octave].data(), ro.data(), io.data());
 
-    vector<double> shifted;
+    RealSequence shifted;
     shifted.insert(shifted.end(), 
                    m_buffers[octave].begin() + m_p.fftHop,
                    m_buffers[octave].end());
--- a/cpp-qm-dsp/ConstantQ.h	Fri May 09 10:56:23 2014 +0100
+++ b/cpp-qm-dsp/ConstantQ.h	Fri May 09 11:15:56 2014 +0100
@@ -103,7 +103,7 @@
     int m_bigBlockSize;
 
     std::vector<Resampler *> m_decimators;
-    RealBlock m_buffers;
+    std::vector<RealSequence> m_buffers;
 
     int m_outputLatency;