Mercurial > hg > qm-dsp
comparison dsp/rateconversion/Resampler.cpp @ 373:395771a6db7f
Avoid int overflow in resample; tidy
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Fri, 18 Oct 2013 11:11:41 +0100 |
parents | d464286c007b |
children | 734e5fa6f731 |
comparison
equal
deleted
inserted
replaced
372:d464286c007b | 373:395771a6db7f |
---|---|
68 | 68 |
69 filter = vector<double>(m_filterLength, 0.0); | 69 filter = vector<double>(m_filterLength, 0.0); |
70 for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; | 70 for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; |
71 sw.cut(filter.data()); | 71 sw.cut(filter.data()); |
72 kw.cut(filter.data()); | 72 kw.cut(filter.data()); |
73 /* | 73 |
74 std::cerr << "sinc for " << params.length << ", " << params.beta | |
75 << ": "; | |
76 for (int i = 0; i < 10; ++i) { | |
77 std::cerr << sw.getWindow()[i] << " "; | |
78 } | |
79 std::cerr << std::endl; | |
80 | |
81 std::cerr << "kaiser for " << params.length << ", " << params.beta | |
82 << ": "; | |
83 for (int i = 0; i < 10; ++i) { | |
84 std::cerr << kw.getWindow()[i] << " "; | |
85 } | |
86 std::cerr << std::endl; | |
87 | |
88 std::cerr << "filter for " << params.length << ", " << params.beta | |
89 << ": "; | |
90 for (int i = 0; i < 10; ++i) { | |
91 std::cerr << filter[i] << " "; | |
92 } | |
93 std::cerr << std::endl; | |
94 */ | |
95 knownFilters[peakToPole][m_filterLength][params.beta] = filter; | 74 knownFilters[peakToPole][m_filterLength][params.beta] = filter; |
96 } | 75 } |
97 | 76 |
98 filter = knownFilters[peakToPole][m_filterLength][params.beta]; | 77 filter = knownFilters[peakToPole][m_filterLength][params.beta]; |
99 knownFilterMutex.unlock(); | 78 knownFilterMutex.unlock(); |
215 // filter length has been provided as input. This means we must | 194 // filter length has been provided as input. This means we must |
216 // either return a very variable number of samples (none at all | 195 // either return a very variable number of samples (none at all |
217 // until the filter fills, then half the filter length at once) or | 196 // until the filter fills, then half the filter length at once) or |
218 // else have a lengthy declared latency on the output. We do the | 197 // else have a lengthy declared latency on the output. We do the |
219 // latter. (What do other implementations do?) | 198 // latter. (What do other implementations do?) |
220 | 199 // |
221 int centreToEnd = (m_filterLength/2) + 1; // from centre of filter | |
222 // to first sample after | |
223 // filter end | |
224 | |
225 // We want to make sure the first "real" sample will eventually be | 200 // We want to make sure the first "real" sample will eventually be |
226 // aligned with the centre sample in the filter (it's tidier, and | 201 // aligned with the centre sample in the filter (it's tidier, and |
227 // easier to do diagnostic calculations that way). So we need to | 202 // easier to do diagnostic calculations that way). So we need to |
228 // pick the initial phase and buffer fill accordingly. | 203 // pick the initial phase and buffer fill accordingly. |
229 // | 204 // |
276 { | 251 { |
277 Phase &pd = m_phaseData[m_phase]; | 252 Phase &pd = m_phaseData[m_phase]; |
278 double v = 0.0; | 253 double v = 0.0; |
279 int n = pd.filter.size(); | 254 int n = pd.filter.size(); |
280 | 255 |
281 assert(n + m_bufferOrigin <= m_buffer.size()); | 256 assert(n + m_bufferOrigin <= (int)m_buffer.size()); |
282 | 257 |
283 const double *const __restrict__ buf = m_buffer.data() + m_bufferOrigin; | 258 const double *const __restrict__ buf = m_buffer.data() + m_bufferOrigin; |
284 const double *const __restrict__ filt = pd.filter.data(); | 259 const double *const __restrict__ filt = pd.filter.data(); |
285 | 260 |
286 // std::cerr << "phase = " << m_phase << ", drop = " << pd.drop << ", buffer for reconstruction starts..."; | 261 // std::cerr << "phase = " << m_phase << ", drop = " << pd.drop << ", buffer for reconstruction starts..."; |
339 | 314 |
340 // latency is the output latency. We need to provide enough | 315 // latency is the output latency. We need to provide enough |
341 // padding input samples at the end of input to guarantee at | 316 // padding input samples at the end of input to guarantee at |
342 // *least* the latency's worth of output samples. that is, | 317 // *least* the latency's worth of output samples. that is, |
343 | 318 |
344 int inputPad = int(ceil(double(latency * sourceRate) / targetRate)); | 319 int inputPad = int(ceil((double(latency) * sourceRate) / targetRate)); |
345 | 320 |
346 // that means we are providing this much input in total: | 321 // that means we are providing this much input in total: |
347 | 322 |
348 int n1 = n + inputPad; | 323 int n1 = n + inputPad; |
349 | 324 |
350 // and obtaining this much output in total: | 325 // and obtaining this much output in total: |
351 | 326 |
352 int m1 = int(ceil(double(n1 * targetRate) / sourceRate)); | 327 int m1 = int(ceil((double(n1) * targetRate) / sourceRate)); |
353 | 328 |
354 // in order to return this much output to the user: | 329 // in order to return this much output to the user: |
355 | 330 |
356 int m = int(ceil(double(n * targetRate) / sourceRate)); | 331 int m = int(ceil((double(n) * targetRate) / sourceRate)); |
357 | 332 |
358 // std::cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << std::endl; | 333 // std::cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", inputPad = " << inputPad << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << std::endl; |
359 | 334 |
360 vector<double> pad(n1 - n, 0.0); | 335 vector<double> pad(n1 - n, 0.0); |
361 vector<double> out(m1 + 1, 0.0); | 336 vector<double> out(m1 + 1, 0.0); |
362 | 337 |
363 int got = r.process(data, out.data(), n); | 338 int got = r.process(data, out.data(), n); |