Mercurial > hg > qm-dsp
comparison dsp/rateconversion/Resampler.cpp @ 419:7ead6122aef7
Slightly simplify resampler
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 07 Oct 2015 09:33:28 +0100 |
parents | 9f7059d8188c |
children | fdaa63607c15 |
comparison
equal
deleted
inserted
replaced
414:7e8d1f26b098 | 419:7ead6122aef7 |
---|---|
15 #include "Resampler.h" | 15 #include "Resampler.h" |
16 | 16 |
17 #include "maths/MathUtilities.h" | 17 #include "maths/MathUtilities.h" |
18 #include "base/KaiserWindow.h" | 18 #include "base/KaiserWindow.h" |
19 #include "base/SincWindow.h" | 19 #include "base/SincWindow.h" |
20 #include "thread/Thread.h" | |
21 | 20 |
22 #include <iostream> | 21 #include <iostream> |
23 #include <vector> | 22 #include <vector> |
24 #include <map> | 23 #include <map> |
25 #include <cassert> | 24 #include <cassert> |
25 #include <algorithm> | |
26 | 26 |
27 using std::vector; | 27 using std::vector; |
28 using std::map; | 28 using std::map; |
29 using std::cerr; | 29 using std::cerr; |
30 using std::endl; | 30 using std::endl; |
34 | 34 |
35 Resampler::Resampler(int sourceRate, int targetRate) : | 35 Resampler::Resampler(int sourceRate, int targetRate) : |
36 m_sourceRate(sourceRate), | 36 m_sourceRate(sourceRate), |
37 m_targetRate(targetRate) | 37 m_targetRate(targetRate) |
38 { | 38 { |
39 #ifdef DEBUG_RESAMPLER | |
40 cerr << "Resampler::Resampler(" << sourceRate << "," << targetRate << ")" << endl; | |
41 #endif | |
39 initialise(100, 0.02); | 42 initialise(100, 0.02); |
40 } | 43 } |
41 | 44 |
42 Resampler::Resampler(int sourceRate, int targetRate, | 45 Resampler::Resampler(int sourceRate, int targetRate, |
43 double snr, double bandwidth) : | 46 double snr, double bandwidth) : |
50 Resampler::~Resampler() | 53 Resampler::~Resampler() |
51 { | 54 { |
52 delete[] m_phaseData; | 55 delete[] m_phaseData; |
53 } | 56 } |
54 | 57 |
55 // peakToPole -> length -> beta -> window | |
56 static map<double, map<int, map<double, vector<double> > > > | |
57 knownFilters; | |
58 | |
59 static Mutex | |
60 knownFilterMutex; | |
61 | |
62 void | 58 void |
63 Resampler::initialise(double snr, double bandwidth) | 59 Resampler::initialise(double snr, double bandwidth) |
64 { | 60 { |
65 int higher = std::max(m_sourceRate, m_targetRate); | 61 int higher = std::max(m_sourceRate, m_targetRate); |
66 int lower = std::min(m_sourceRate, m_targetRate); | 62 int lower = std::min(m_sourceRate, m_targetRate); |
83 (params.length > 200001 ? 200001 : params.length); | 79 (params.length > 200001 ? 200001 : params.length); |
84 | 80 |
85 m_filterLength = params.length; | 81 m_filterLength = params.length; |
86 | 82 |
87 vector<double> filter; | 83 vector<double> filter; |
88 knownFilterMutex.lock(); | 84 |
89 | 85 KaiserWindow kw(params); |
90 if (knownFilters[m_peakToPole][m_filterLength].find(params.beta) == | 86 SincWindow sw(m_filterLength, m_peakToPole * 2); |
91 knownFilters[m_peakToPole][m_filterLength].end()) { | 87 |
92 | 88 filter = vector<double>(m_filterLength, 0.0); |
93 KaiserWindow kw(params); | 89 for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; |
94 SincWindow sw(m_filterLength, m_peakToPole * 2); | 90 sw.cut(filter.data()); |
95 | 91 kw.cut(filter.data()); |
96 filter = vector<double>(m_filterLength, 0.0); | 92 |
97 for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; | |
98 sw.cut(filter.data()); | |
99 kw.cut(filter.data()); | |
100 | |
101 knownFilters[m_peakToPole][m_filterLength][params.beta] = filter; | |
102 } | |
103 | |
104 filter = knownFilters[m_peakToPole][m_filterLength][params.beta]; | |
105 knownFilterMutex.unlock(); | |
106 | |
107 int inputSpacing = m_targetRate / m_gcd; | 93 int inputSpacing = m_targetRate / m_gcd; |
108 int outputSpacing = m_sourceRate / m_gcd; | 94 int outputSpacing = m_sourceRate / m_gcd; |
109 | 95 |
110 #ifdef DEBUG_RESAMPLER | 96 #ifdef DEBUG_RESAMPLER |
111 cerr << "resample " << m_sourceRate << " -> " << m_targetRate | 97 cerr << "resample " << m_sourceRate << " -> " << m_targetRate |
291 { | 277 { |
292 Phase &pd = m_phaseData[m_phase]; | 278 Phase &pd = m_phaseData[m_phase]; |
293 double v = 0.0; | 279 double v = 0.0; |
294 int n = pd.filter.size(); | 280 int n = pd.filter.size(); |
295 | 281 |
296 assert(n + m_bufferOrigin <= (int)m_buffer.size()); | 282 if (n + m_bufferOrigin > (int)m_buffer.size()) { |
297 | 283 cerr << "ERROR: n + m_bufferOrigin > m_buffer.size() [" << n << " + " |
298 const double *const __restrict__ buf = m_buffer.data() + m_bufferOrigin; | 284 << m_bufferOrigin << " > " << m_buffer.size() << "]" << endl; |
299 const double *const __restrict__ filt = pd.filter.data(); | 285 throw std::logic_error("n + m_bufferOrigin > m_buffer.size()"); |
286 } | |
287 | |
288 #if defined(__MSVC__) | |
289 #define R__ __restrict | |
290 #elif defined(__GNUC__) | |
291 #define R__ __restrict__ | |
292 #else | |
293 #define R__ | |
294 #endif | |
295 | |
296 const double *const R__ buf(m_buffer.data() + m_bufferOrigin); | |
297 const double *const R__ filt(pd.filter.data()); | |
300 | 298 |
301 for (int i = 0; i < n; ++i) { | 299 for (int i = 0; i < n; ++i) { |
302 // NB gcc can only vectorize this with -ffast-math | 300 // NB gcc can only vectorize this with -ffast-math |
303 v += buf[i] * filt[i]; | 301 v += buf[i] * filt[i]; |
304 } | 302 } |
309 } | 307 } |
310 | 308 |
311 int | 309 int |
312 Resampler::process(const double *src, double *dst, int n) | 310 Resampler::process(const double *src, double *dst, int n) |
313 { | 311 { |
314 for (int i = 0; i < n; ++i) { | 312 m_buffer.insert(m_buffer.end(), src, src + n); |
315 m_buffer.push_back(src[i]); | |
316 } | |
317 | 313 |
318 int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate)); | 314 int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate)); |
319 int outidx = 0; | 315 int outidx = 0; |
320 | 316 |
321 #ifdef DEBUG_RESAMPLER | 317 #ifdef DEBUG_RESAMPLER |
326 | 322 |
327 while (outidx < maxout && | 323 while (outidx < maxout && |
328 m_buffer.size() >= m_phaseData[m_phase].filter.size() + m_bufferOrigin) { | 324 m_buffer.size() >= m_phaseData[m_phase].filter.size() + m_bufferOrigin) { |
329 dst[outidx] = scaleFactor * reconstructOne(); | 325 dst[outidx] = scaleFactor * reconstructOne(); |
330 outidx++; | 326 outidx++; |
327 } | |
328 | |
329 if (m_bufferOrigin > (int)m_buffer.size()) { | |
330 cerr << "ERROR: m_bufferOrigin > m_buffer.size() [" | |
331 << m_bufferOrigin << " > " << m_buffer.size() << "]" << endl; | |
332 throw std::logic_error("m_bufferOrigin > m_buffer.size()"); | |
331 } | 333 } |
332 | 334 |
333 m_buffer = vector<double>(m_buffer.begin() + m_bufferOrigin, m_buffer.end()); | 335 m_buffer = vector<double>(m_buffer.begin() + m_bufferOrigin, m_buffer.end()); |
334 m_bufferOrigin = 0; | 336 m_bufferOrigin = 0; |
335 | 337 |