28 #define SAMPLE_RATE 48000 41 #include <sys/types.h> 56 gettimeofday(&tp, NULL);
57 ret = ((double) tp.tv_sec) + 1e-6*((double)tp.tv_usec);
61 static void bindump(
char * fn, std::complex<float> * buf,
unsigned int num_elts) __attribute__ ((unused));
62 static void bindump(
char * fn, std::complex<float> * buf,
unsigned int num_elts)
67 for(i = 0; i < num_elts; i++) {
68 fprintf(of,
"%d %g %g\n", i, buf[i].real(), buf[i].imag());
74 float anginc,
unsigned int iM,
unsigned int dN,
76 std::complex<float> * invec, std::complex<float> * outvec,
int idx = 0)
82 unsigned int outlen = inlen * iM;
86 float oanginc = anginc * ((float) dN) / ((float) iM);
90 float err_sq_sum[2] = { 0.0, 0.0 };
91 for(i = 0; i < outlen; i++) {
93 fprintf(ofile,
"%d\t%g\t%g\t%g\t%g\t%g\t", i + idx*outlen, ang, outvec[i].real(), outvec[i].imag(), cos(ang), sin(ang));
94 float err = outvec[i].real() - cos(ang);
95 err_sq_sum[0] += err * err;
96 fprintf(ofile,
"%g\t", err);
97 err = outvec[i].imag() - sin(ang);
98 err_sq_sum[1] += err * err;
99 fprintf(ofile,
"%g\n", err);
101 if(ang > M_PI) ang = ang - (2.0 * M_PI);
104 fprintf(ofile,
"%d\t%g\t%g\t%g\t%g\t%g\t%g\t%g\n", i + idx*outlen, ang+0.5*anginc, 5.0, 5.0, cos(ang), sin(ang), 1.0, 1.0);
105 float fn = (float) outlen;
106 printf(
"RMS error for M/N = %d / %d : %g %g\n",
107 iM, dN, sqrt(err_sq_sum[0]/fn), sqrt(err_sq_sum[1]/fn));
110 float loadVector(
float ang,
float ang_inc, std::complex<float> * vec,
int len)
113 for(i = 0; i < len; i++) {
114 vec[i] = std::complex<float>(cos(ang), sin(ang));
117 if((ii == 0) || (ii == 5) || (ii == 7) || (ii == 10)) ang += ang_inc;
118 if(ang > M_PI) ang -= (2.0 * M_PI);
127 float in[60000], out[2304];
128 std::complex<float> cin[60000], cout[2304];
132 for(i = 0; i < 60000; i++) {
134 cin[i] = std::complex<float>(sin(ang), cos(ang));
140 rsf.
apply(in + 30000, out);
141 rsc.
apply(cin, cout);
142 rsc.
apply(cin + 30000, cout);
144 for(i = 0; i < 30000; i++) {
146 std::cout << boost::format(
"%d %f %f %f ") % i % in[j] % cin[j].real() % cin[j].imag();
148 std::cout << boost::format(
"%f %f %f\n") % out[i] % cout[i].real() % cout[i].imag();
151 std::cout << std::endl;
164 std::complex<float> cin[30000], cout[2304];
166 ofstream to(
"ReSampler625to48_Test.dat");
169 float samp_freq = 625000.0;
172 for(test_freq = -312500.0; test_freq < 312500.0; ) {
174 float phase_advance_per_tic = 2.0 * M_PI * test_freq / samp_freq;
176 for(i = 0; i < 100; i++) {
178 for(j = 0; j < 30000; j++) {
179 cin[j] = std::complex<float>(cos(angle), sin(angle));
180 angle += phase_advance_per_tic;
181 if(angle > M_PI) angle -= (2.0 * M_PI);
182 if(angle < -M_PI) angle += (2.0 * M_PI);
184 rsf.
apply(cin, cout);
186 for(j = 0; j < 2304; j++) {
187 float ip = cout[j].real();
188 float qu = cout[j].imag();
189 energy += ip * ip + qu * qu;
193 to << boost::format(
"%f %f\n") % test_freq % (10.0 * log10(energy));
194 std::cout << boost::format(
"%f %f\n") % test_freq % (10.0 * log10(energy));
195 if(test_freq < 0.0) {
196 if(test_freq > -10.0) test_freq = 10.0;
197 else test_freq *= (1.0 / 1.05);
207 int main(
int argc,
char * argv[])
209 (void) argc; (void) argv;
212 unsigned int resampler_ratio[][2] = { { 5, 1 },
219 std::complex<float> invec[30000];
220 std::complex<float> outvec[30000];
221 std::complex<float> out2vec[30000];
233 float ang_inc = 2.0 * M_PI * 315.26 / 6000.0;
238 for(j = 0; j < 2; j++) {
239 for(i = 0; resampler_ratio[i][0] > 0; i++) {
241 iM = resampler_ratio[i][j];
242 dN = resampler_ratio[i][1-j];
245 sprintf(buf,
"resample_%d_%d.dat", iM, dN);
246 FILE * ofile = fopen(buf,
"w");
251 rs->
apply(invec, outvec);
254 rs->
apply(invec, outvec);
257 checkResult(ofile, ang_inc, iM, dN, 6000, invec, outvec, 0);
259 rs->
apply(invec, outvec);
260 checkResult(ofile, ang_inc, iM, dN, 6000, invec, outvec, 1);
262 rs->
apply(invec, outvec);
263 checkResult(ofile, ang_inc, iM, dN, 6000, invec, outvec, 2);
265 rs->
apply(invec, outvec);
266 checkResult(ofile, ang_inc, iM, dN, 6000, invec, outvec, 3);
267 std::cout <<
"TIM: Resample took " << (endt - startt) <<
" seconds" << std::endl;
279 for(i = 0; i < 4000; i++) {
280 up->
apply(invec, outvec);
281 down->
apply(outvec, invec);
285 std::cout <<
"TIM: average time per up/down resampling pair: " 286 << (ttend - ttstart) / ((
double) i) << std::endl;
295 ang_inc = 2.0 * M_PI / 53.7;
297 float ang2_inc = 2.0 * M_PI * 3.0 / 4.0;
298 for(i = 0; i < 30000; i++) {
300 invec[i] = std::complex<float>(cos(ang), sin(ang));
302 if(ang > M_PI) ang -= 2.0 * M_PI;
304 if(ang2 > M_PI) ang2 -= 2.0 * M_PI;
307 int uf = creat(
"up_1khz_625k.dat", 0666);
310 rs54a.apply(invec, outvec);
311 rs54b.
apply(outvec, out2vec);
312 rs53.
apply(out2vec, outvec);
313 rs51.
apply(outvec, out2vec);
315 std::cout <<
"Upsampled from 2304 to 30000 in 5/4 5/4 5/3 5/1 in " 316 << (ttend - ttstart) <<
" seconds" << std::endl;
317 int stat = write(uf, out2vec,
sizeof(std::complex<float>) * 30000);
319 rs54a.apply(invec, outvec);
320 rs54b.
apply(outvec, out2vec);
321 rs53.
apply(out2vec, outvec);
322 rs51.
apply(outvec, out2vec);
323 stat = write(uf, out2vec,
sizeof(std::complex<float>) * 30000);
324 rs54a.apply(invec, outvec);
325 rs54b.
apply(outvec, out2vec);
326 rs53.
apply(out2vec, outvec);
327 rs51.
apply(outvec, out2vec);
328 stat = write(uf, out2vec,
sizeof(std::complex<float>) * 30000);
329 rs54a.apply(invec, outvec);
330 rs54b.
apply(outvec, out2vec);
331 rs53.
apply(out2vec, outvec);
332 rs51.
apply(outvec, out2vec);
333 stat = write(uf, out2vec,
sizeof(std::complex<float>) * 30000);
341 rs54a.apply(invec, outvec);
342 rs53b.
apply(invec, outvec);
343 rs52a.
apply(outvec, invec);
344 rs52b.
apply(outvec, invec);
346 std::cout <<
"Upsampled from 2304 to 30000 in 5/4 5/3 5/2 5/2 in " 347 << (ttend - ttstart) <<
" seconds" << std::endl;
359 ang_inc = 2.0 * M_PI / 50.0;
360 for(i = 0; i < 30000; i++) {
361 invec[i] = std::complex<float>(cos(ang), sin(ang));
363 if(ang > M_PI) ang -= 2.0 * M_PI;
366 rs15.apply(invec, outvec);
367 rs35.
apply(outvec, out2vec);
368 rs45a.
apply(out2vec, outvec);
369 rs45b.
apply(outvec, out2vec);
371 std::cout <<
"Downsampled from 30000 to 2304 in 1/5 3/5 4/5 4/5 in " 372 << (ttend - ttstart) <<
" seconds" << std::endl;
374 int df = creat(
"down_1khz_625k.dat", 0666);
375 stat = write(df, out2vec,
sizeof(std::complex<float>) * 2304);
376 rs15.apply(invec, outvec);
377 rs35.
apply(outvec, out2vec);
378 rs45a.
apply(out2vec, outvec);
379 rs45b.
apply(outvec, out2vec);
380 stat = write(df, out2vec,
sizeof(std::complex<float>) * 2304);
382 rs15.apply(invec, outvec);
383 rs35.
apply(outvec, out2vec);
384 rs45a.
apply(out2vec, outvec);
385 rs45b.
apply(outvec, out2vec);
386 stat = write(df, out2vec,
sizeof(std::complex<float>) * 2304);
394 rs25b.
apply(outvec, invec);
395 rs25a.
apply(outvec, invec);
396 rs35b.
apply(invec, outvec);
397 rs45b.
apply(invec, outvec);
401 std::cout <<
"Downsampled from 30000 to 2304 in 2/5 2/5 3/5 1/5 in " 402 << (ttend - ttstart) <<
" seconds" << std::endl;
Resampler for 625KHz to 48KHz data stream, built on rational ReSampler class.
void checkResult(FILE *ofile, float anginc, unsigned int iM, unsigned int dN, unsigned int inlen, std::complex< float > *invec, std::complex< float > *outvec, int idx=0)
int main(int argc, char *argv[])
void apply(std::complex< float > *in, std::complex< float > *out)
Perform the resampling on a complex float buffer.
static void bindump(char *fn, std::complex< float > *buf, unsigned int num_elts) __attribute__((unused))
float loadVector(float ang, float ang_inc, std::complex< float > *vec, int len)
unsigned int apply(std::complex< float > *in, std::complex< float > *out, float gain=1.0)
apply the resampler to a buffer of IQ samples.