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