changeset 76:5d3ab532d8af

Linear interpolation fixed
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 04 Apr 2014 12:33:15 +0100
parents f4fb0ac6120a
children f2d747d234d5
files cpp-qm-dsp/CQInterpolated.cpp cpp-qm-dsp/CQInterpolated.h
diffstat 2 files changed, 55 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/cpp-qm-dsp/CQInterpolated.cpp	Fri Apr 04 11:49:53 2014 +0100
+++ b/cpp-qm-dsp/CQInterpolated.cpp	Fri Apr 04 12:33:15 2014 +0100
@@ -32,6 +32,7 @@
 #include "CQInterpolated.h"
 
 #include <iostream>
+#include <stdexcept>
 
 using std::vector;
 
@@ -64,7 +65,7 @@
 }
 
 vector<vector<double> >
-CQInterpolated::postProcess(vector<vector<double> > cq, bool insist)
+CQInterpolated::postProcess(const vector<vector<double> > &cq, bool insist)
 {
     if (m_interpolation == None) {
 	return cq;
@@ -184,26 +185,7 @@
 	}
     } else {
 	// firstFullHeight == 0 and secondFullHeight also valid. Can interpolate
-
-	out.push_back(m_buffer[0]);
-
-	for (int i = 1; i < secondFullHeight; ++i) {
-
-	    vector<double> col = m_buffer[i];
-	    int thisHeight = col.size();
-
-	    double proportion = double(i) / double(secondFullHeight);
-
-	    cerr << "secondFullHeight = " << secondFullHeight << " proportion = " << proportion << " ";
-
-	    for (int j = thisHeight; j < height; ++j) {
-		col.push_back((1.0 - proportion) * m_buffer[0][j]
-			      + proportion * m_buffer[secondFullHeight][j]);
-	    }
-
-	    out.push_back(col);
-	}
-
+	out = linearInterpolated(m_buffer, 0, secondFullHeight);
 	m_buffer = Grid(m_buffer.begin() + secondFullHeight, m_buffer.end());
 	Grid more = fetchLinear(insist);
 	out.insert(out.end(), more.begin(), more.end());
@@ -211,5 +193,55 @@
     }
 }
 
+vector<vector<double> >
+CQInterpolated::linearInterpolated(const Grid &g, int x0, int x1)
+{
+    // g must be a grid with full-height columns at x0 and x1
+
+    if (x0 >= x1) {
+	throw std::logic_error("x0 >= x1");
+    }
+    if (x1 >= g.size()) {
+	throw std::logic_error("x1 >= g.size()");
+    }
+    if (g[x0].size() != g[x1].size()) {
+	throw std::logic_error("x0 and x1 are not the same height");
+    }
+
+    int height = g[x0].size();
+    int width = x1 - x0;
+
+    Grid out(g.begin() + x0, g.begin() + x1);
+
+    for (int y = 0; y < height; ++y) {
+
+	int spacing = width;
+	for (int i = 1; i < width; ++i) {
+	    int thisHeight = g[x0 + i].size();
+	    if (thisHeight > height) {
+		throw std::logic_error("First column not full-height");
+	    }
+	    if (thisHeight > y) {
+		spacing = i;
+		break;
+	    }
+	}
+
+	if (spacing < 2) continue;
+
+	for (int i = 0; i + spacing <= width; i += spacing) {
+	    for (int j = 1; j < spacing; ++j) {
+		double proportion = double(j)/double(spacing);
+		double interpolated = 
+		    g[x0 + i][y] * (1.0 - proportion) +
+		    g[x0 + i + spacing][y] * proportion;
+		out[i + j].push_back(interpolated);
+	    }
+	}
+    }
+
+    return out;
+}
+
 
 	
--- a/cpp-qm-dsp/CQInterpolated.h	Fri Apr 04 11:49:53 2014 +0100
+++ b/cpp-qm-dsp/CQInterpolated.h	Fri Apr 04 12:33:15 2014 +0100
@@ -69,9 +69,10 @@
 
     typedef std::vector<std::vector<double> > Grid;
     Grid m_buffer;
-    Grid postProcess(Grid, bool insist);
+    Grid postProcess(const Grid &, bool insist);
     Grid fetchHold(bool insist);
     Grid fetchLinear(bool insist);
+    Grid linearInterpolated(const Grid &, int, int);
     std::vector<double> m_prevColumn;
 };