changeset 34:e9752aa1b234

More on reconstructing CQ shape. This is not always correct yet, though
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 06 Nov 2013 14:30:19 +0000
parents f6ef28b02be4
children 75d528478feb
files cpp-qm-dsp/ConstantQ.cpp cpp-qm-dsp/ConstantQ.h cpp-qm-dsp/Makefile
diffstat 3 files changed, 52 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/cpp-qm-dsp/ConstantQ.cpp	Wed Nov 06 09:09:55 2013 +0000
+++ b/cpp-qm-dsp/ConstantQ.cpp	Wed Nov 06 14:30:19 2013 +0000
@@ -69,7 +69,8 @@
     m_decimators.push_back(0);
 
     for (int oct = 1; oct < m_octaves; ++oct) {
-	Resampler *r = new Resampler(sourceRate, sourceRate / pow(2, oct));
+	Resampler *r = new Resampler
+	    (sourceRate, sourceRate / pow(2, oct), 60, 0.02);
 	latencies.push_back(r->getLatency());
 	m_decimators.push_back(r);
     }
@@ -105,50 +106,51 @@
     //!!!! need some mechanism for handling remaining samples at the end
 
     while (m_buffers[0].size() >= m_bigBlockSize) {
-	vector<vector<double> > chunk = processBigBlock();
-	for (int i = 0; i < m_octaves; ++i) {
-	    vector<double> v;
-	    v.insert(v.end(),
-		     m_buffers[i].begin() + m_bigBlockSize/pow(2,i), m_buffers[i].end());
-	    m_buffers[i] = v;
+
+	int base = out.size();
+	int totalColumns = pow(2, m_octaves - 1) * m_p.atomsPerFrame;
+	cerr << "totalColumns = " << totalColumns << endl;
+	for (int i = 0; i < totalColumns; ++i) {
+	    out.push_back(vector<double>());
 	}
-	out.insert(out.end(), chunk.begin(), chunk.end());
+
+	for (int octave = 0; octave < m_octaves; ++octave) {
+
+	    int blocksThisOctave = pow(2, (m_octaves - octave - 1));
+//	    cerr << "octave " << octave+1 << " of " << m_octaves << ", n = " << blocksThisOctave << endl;
+
+	    for (int b = 0; b < blocksThisOctave; ++b) {
+		vector<vector<double> > block = processOctaveBlock(octave);
+		
+		for (int j = 0; j < m_p.atomsPerFrame; ++j) {
+		    int target = base +
+			(b * (totalColumns / blocksThisOctave) + 
+			 (j * ((totalColumns / blocksThisOctave) / m_p.atomsPerFrame)));
+//		    cerr << "j " << j << " -> target " << target << endl;
+		    for (int i = 0; i < m_p.binsPerOctave; ++i) {
+			out[target].push_back(block[j][m_p.binsPerOctave-i-1]);
+		    }
+		}
+	    }
+	}
     }
     
     return out;
 }
 
-vector<vector<double> > 
-ConstantQ::processBigBlock()
-{
-    vector<vector<double> > out;
-
-    for (int i = 0; i < pow(2, m_octaves - 1) * m_p.atomsPerFrame; ++i) {
-	out.push_back(vector<double>());
-    }
-    cerr << "returning " << out.size() << " cols per big block" << endl;
-
-    for (int i = 0; i < m_octaves; ++i) {
-	int n = pow(2, (m_octaves - i - 1));
-	cerr << "octave " << i+1 << " of " << m_octaves << ", n = " << n << endl;
-	for (int j = 0; j < n; ++j) {
-	    int origin = j * m_p.fftSize; //!!! no -- it's the hop but how does that add up?
-	    vector<vector<double> > block = 
-		processOctaveBlock(m_buffers[i].data() + origin);
-
-	    //...
-	}
-    }
-
-    return out;
-}
-	
 vector<vector<double> >
-ConstantQ::processOctaveBlock(const double *data)
+ConstantQ::processOctaveBlock(int octave)
 {
     vector<double> ro(m_p.fftSize, 0.0);
     vector<double> io(m_p.fftSize, 0.0);
-    m_fft->forward(data, ro.data(), io.data());
+
+    m_fft->forward(m_buffers[octave].data(), ro.data(), io.data());
+
+    vector<double> shifted;
+    shifted.insert(shifted.end(), 
+		   m_buffers[octave].begin() + m_p.fftHop,
+		   m_buffers[octave].end());
+    m_buffers[octave] = shifted;
 
     vector<C> cv;
     for (int i = 0; i < m_p.fftSize; ++i) {
@@ -157,11 +159,12 @@
 
     vector<C> cqrowvec = m_kernel->process(cv);
 
+    // Reform into a column matrix 
     vector<vector<double> > cqblock;
-    for (int i = 0; i < m_p.binsPerOctave; ++i) {
+    for (int j = 0; j < m_p.atomsPerFrame; ++j) {
 	cqblock.push_back(vector<double>());
-	for (int j = 0; j < m_p.atomsPerFrame; ++j) {
-	    cqblock[i].push_back(abs(cqrowvec[i * m_p.atomsPerFrame + j]));
+	for (int i = 0; i < m_p.binsPerOctave; ++i) {
+	    cqblock[j].push_back(abs(cqrowvec[i * m_p.atomsPerFrame + j]));
 	}
     }
 
--- a/cpp-qm-dsp/ConstantQ.h	Wed Nov 06 09:09:55 2013 +0000
+++ b/cpp-qm-dsp/ConstantQ.h	Wed Nov 06 14:30:19 2013 +0000
@@ -18,6 +18,14 @@
 	      int binsPerOctave);
     ~ConstantQ();
 
+    double getSampleRate() const { return m_sampleRate; }
+    double getMaxFrequency() const { return m_p.maxFrequency; }
+    double getMinFrequency() const { return m_p.minFrequency; } // actual min, not that provided to ctor
+    int getBinsPerOctave() const { return m_binsPerOctave; }
+    int getOctaves() const { return m_octaves; }
+    int getTotalBins() const { return m_octaves * m_binsPerOctave; }
+    int getColumnHop() const { return m_p.fftHop / m_p.atomsPerFrame; }
+
     std::vector<std::vector<double> > process(std::vector<double>);
 
 private:
@@ -40,8 +48,7 @@
     FFTReal *m_fft;
 
     void initialise();
-    std::vector<std::vector<double> > processBigBlock();
-    std::vector<std::vector<double> > processOctaveBlock(const double *data);
+    std::vector<std::vector<double> > processOctaveBlock(int octave);
 };
 
 #endif
--- a/cpp-qm-dsp/Makefile	Wed Nov 06 09:09:55 2013 +0000
+++ b/cpp-qm-dsp/Makefile	Wed Nov 06 14:30:19 2013 +0000
@@ -3,8 +3,8 @@
 
 CFLAGS := -I../.. $(CFLAGS) $(DEFINES)
 
-CXXFLAGS := -I../.. -Wall -g $(CXXFLAGS) $(DEFINES)
-#CXXFLAGS := -I../.. -Wall -O3 -ffast-math -ftree-vectorize $(CXXFLAGS) $(DEFINES)
+#CXXFLAGS := -I../.. -fPIC -Wall -g $(CXXFLAGS) $(DEFINES)
+CXXFLAGS := -I../.. -fPIC -Wall -O3 -ffast-math -ftree-vectorize $(CXXFLAGS) $(DEFINES)
 
 LDFLAGS := $(LDFLAGS)