Mercurial > hg > qm-dsp
comparison 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 |
comparison
equal
deleted
inserted
replaced
367:0721657fdd1d | 368:ee8ace7fdc88 |
---|---|
41 params.length = | 41 params.length = |
42 (params.length % 2 == 0 ? params.length + 1 : params.length); | 42 (params.length % 2 == 0 ? params.length + 1 : params.length); |
43 | 43 |
44 m_filterLength = params.length; | 44 m_filterLength = params.length; |
45 | 45 |
46 std::cerr << "making filter... "; | |
46 KaiserWindow kw(params); | 47 KaiserWindow kw(params); |
47 SincWindow sw(m_filterLength, peakToPole * 2); | 48 SincWindow sw(m_filterLength, peakToPole * 2); |
49 std::cerr << "done" << std::endl; | |
48 | 50 |
49 double *filter = new double[m_filterLength]; | 51 double *filter = new double[m_filterLength]; |
50 for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; | 52 for (int i = 0; i < m_filterLength; ++i) filter[i] = 1.0; |
51 sw.cut(filter); | 53 sw.cut(filter); |
52 kw.cut(filter); | 54 kw.cut(filter); |
136 | 138 |
137 double | 139 double |
138 Resampler::reconstructOne() | 140 Resampler::reconstructOne() |
139 { | 141 { |
140 Phase &pd = m_phaseData[m_phase]; | 142 Phase &pd = m_phaseData[m_phase]; |
141 double *filt = pd.filter.data(); | |
142 double v = 0.0; | 143 double v = 0.0; |
143 int n = pd.filter.size(); | 144 int n = pd.filter.size(); |
145 const double *buf = m_buffer.data(); | |
146 const double *filt = pd.filter.data(); | |
144 for (int i = 0; i < n; ++i) { | 147 for (int i = 0; i < n; ++i) { |
145 v += m_buffer[i] * filt[i]; | 148 v += buf[i] * filt[i]; //!!! gcc can't vectorize: why? |
146 } | 149 } |
147 m_buffer = vector<double>(m_buffer.begin() + pd.drop, m_buffer.end()); | 150 m_buffer = vector<double>(m_buffer.begin() + pd.drop, m_buffer.end()); |
148 m_phase = pd.nextPhase; | 151 m_phase = pd.nextPhase; |
149 return v; | 152 return v; |
150 } | 153 } |
165 | 168 |
166 double scaleFactor = 1.0; | 169 double scaleFactor = 1.0; |
167 if (m_targetRate < m_sourceRate) { | 170 if (m_targetRate < m_sourceRate) { |
168 scaleFactor = double(m_targetRate) / double(m_sourceRate); | 171 scaleFactor = double(m_targetRate) / double(m_sourceRate); |
169 } | 172 } |
173 | |
174 std::cerr << "maxout = " << maxout << std::endl; | |
170 | 175 |
171 while (outidx < maxout && | 176 while (outidx < maxout && |
172 m_buffer.size() >= m_phaseData[m_phase].filter.size()) { | 177 m_buffer.size() >= m_phaseData[m_phase].filter.size()) { |
173 dst[outidx] = scaleFactor * reconstructOne(); | 178 dst[outidx] = scaleFactor * reconstructOne(); |
174 outidx++; | 179 outidx++; |
182 { | 187 { |
183 Resampler r(sourceRate, targetRate); | 188 Resampler r(sourceRate, targetRate); |
184 | 189 |
185 int latency = r.getLatency(); | 190 int latency = r.getLatency(); |
186 | 191 |
192 // latency is the output latency. We need to provide enough | |
193 // padding input samples at the end of input to guarantee at | |
194 // *least* the latency's worth of output samples. that is, | |
195 | |
196 int inputPad = int(ceil(double(latency * sourceRate) / targetRate)); | |
197 | |
198 std::cerr << "latency = " << latency << ", inputPad = " << inputPad << std::endl; | |
199 | |
200 // that means we are providing this much input in total: | |
201 | |
202 int n1 = n + inputPad; | |
203 | |
204 // and obtaining this much output in total: | |
205 | |
206 int m1 = int(ceil(double(n1 * targetRate) / sourceRate)); | |
207 | |
208 // in order to return this much output to the user: | |
209 | |
187 int m = int(ceil(double(n * targetRate) / sourceRate)); | 210 int m = int(ceil(double(n * targetRate) / sourceRate)); |
188 int m1 = m + latency; | 211 |
189 int n1 = int(double(m1 * sourceRate) / targetRate); | 212 std::cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << std::endl; |
190 | 213 |
191 vector<double> pad(n1 - n, 0.0); | 214 vector<double> pad(n1 - n, 0.0); |
192 vector<double> out(m1, 0.0); | 215 vector<double> out(m1 + 1, 0.0); |
193 | 216 |
194 int got = r.process(data, out.data(), n); | 217 int got = r.process(data, out.data(), n); |
195 got += r.process(pad.data(), out.data() + got, pad.size()); | 218 got += r.process(pad.data(), out.data() + got, pad.size()); |
196 | 219 |
197 #ifdef DEBUG_RESAMPLER | 220 #ifdef DEBUG_RESAMPLER |
201 std::cout << (float) out[i] << " "; | 224 std::cout << (float) out[i] << " "; |
202 } | 225 } |
203 std::cout << std::endl; | 226 std::cout << std::endl; |
204 #endif | 227 #endif |
205 | 228 |
206 return vector<double>(out.begin() + latency, out.begin() + got); | 229 int toReturn = got - latency; |
207 } | 230 if (toReturn > m) toReturn = m; |
208 | 231 |
232 return vector<double>(out.begin() + latency, | |
233 out.begin() + latency + toReturn); | |
234 } | |
235 |