# HG changeset patch # User Chris Cannam # Date 1396611195 -3600 # Node ID 5d3ab532d8afd47525ea75ee26fe9cd5b9a16f93 # Parent f4fb0ac6120aeed01f82966753b396cfe94b13ba Linear interpolation fixed diff -r f4fb0ac6120a -r 5d3ab532d8af cpp-qm-dsp/CQInterpolated.cpp --- 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 +#include using std::vector; @@ -64,7 +65,7 @@ } vector > -CQInterpolated::postProcess(vector > cq, bool insist) +CQInterpolated::postProcess(const vector > &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 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 > +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; +} + diff -r f4fb0ac6120a -r 5d3ab532d8af cpp-qm-dsp/CQInterpolated.h --- 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 > 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 m_prevColumn; };