Mercurial > hg > qm-dsp
diff dsp/rateconversion/Resampler.cpp @ 368:ee8ace7fdc88
Some fixes, and start on spectrum test
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Tue, 15 Oct 2013 18:27:19 +0100 |
parents | 0721657fdd1d |
children | fe267879e022 |
line wrap: on
line diff
--- a/dsp/rateconversion/Resampler.cpp Mon Oct 14 16:20:00 2013 +0100 +++ b/dsp/rateconversion/Resampler.cpp Tue Oct 15 18:27:19 2013 +0100 @@ -43,8 +43,10 @@ m_filterLength = params.length; + std::cerr << "making filter... "; KaiserWindow kw(params); SincWindow sw(m_filterLength, peakToPole * 2); + std::cerr << "done" << std::endl; double *filter = new double[m_filterLength]; for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; @@ -138,11 +140,12 @@ Resampler::reconstructOne() { Phase &pd = m_phaseData[m_phase]; - double *filt = pd.filter.data(); double v = 0.0; int n = pd.filter.size(); + const double *buf = m_buffer.data(); + const double *filt = pd.filter.data(); for (int i = 0; i < n; ++i) { - v += m_buffer[i] * filt[i]; + v += buf[i] * filt[i]; //!!! gcc can't vectorize: why? } m_buffer = vector<double>(m_buffer.begin() + pd.drop, m_buffer.end()); m_phase = pd.nextPhase; @@ -168,6 +171,8 @@ scaleFactor = double(m_targetRate) / double(m_sourceRate); } + std::cerr << "maxout = " << maxout << std::endl; + while (outidx < maxout && m_buffer.size() >= m_phaseData[m_phase].filter.size()) { dst[outidx] = scaleFactor * reconstructOne(); @@ -184,12 +189,30 @@ int latency = r.getLatency(); + // latency is the output latency. We need to provide enough + // padding input samples at the end of input to guarantee at + // *least* the latency's worth of output samples. that is, + + int inputPad = int(ceil(double(latency * sourceRate) / targetRate)); + + std::cerr << "latency = " << latency << ", inputPad = " << inputPad << std::endl; + + // that means we are providing this much input in total: + + int n1 = n + inputPad; + + // and obtaining this much output in total: + + int m1 = int(ceil(double(n1 * targetRate) / sourceRate)); + + // in order to return this much output to the user: + int m = int(ceil(double(n * targetRate) / sourceRate)); - int m1 = m + latency; - int n1 = int(double(m1 * sourceRate) / targetRate); + + std::cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << std::endl; vector<double> pad(n1 - n, 0.0); - vector<double> out(m1, 0.0); + vector<double> out(m1 + 1, 0.0); int got = r.process(data, out.data(), n); got += r.process(pad.data(), out.data() + got, pad.size()); @@ -203,6 +226,10 @@ std::cout << std::endl; #endif - return vector<double>(out.begin() + latency, out.begin() + got); + int toReturn = got - latency; + if (toReturn > m) toReturn = m; + + return vector<double>(out.begin() + latency, + out.begin() + latency + toReturn); }