// Helper function to keep code base small void resamp2_crcf_bench(struct rusage *_start, struct rusage *_finish, unsigned long int * _num_iterations, unsigned int _m, resamp2_type _type) { // scale number of iterations by filter length // NOTE: n = 4*m+1 // cycles/trial ~ 70.5 + 7.74*_m *_num_iterations *= 200; *_num_iterations /= 70.5 + 7.74*_m; unsigned long int i; resamp2_crcf q = resamp2_crcf_create(_m,0.0f,60.0f); float complex x[] = {1.0f, -1.0f}; float complex y[] = {1.0f, -1.0f}; // start trials getrusage(RUSAGE_SELF, _start); if (_type == RESAMP2_DECIM) { // run decimator for (i=0; i<(*_num_iterations); i++) { resamp2_crcf_decim_execute(q,x,y); resamp2_crcf_decim_execute(q,x,y); resamp2_crcf_decim_execute(q,x,y); resamp2_crcf_decim_execute(q,x,y); } } else { // run interpolator for (i=0; i<(*_num_iterations); i++) { resamp2_crcf_interp_execute(q,x[0],y); resamp2_crcf_interp_execute(q,x[0],y); resamp2_crcf_interp_execute(q,x[0],y); resamp2_crcf_interp_execute(q,x[0],y); } } getrusage(RUSAGE_SELF, _finish); *_num_iterations *= 4; resamp2_crcf_destroy(q); }
int main(int argc, char*argv[]) { unsigned int m=5; // filter semi-length float fc=0.037f; // input tone frequency unsigned int num_samples = 64; // number of output samples float As=60.0f; // stop-band attenuation [dB] int dopt; while ((dopt = getopt(argc,argv,"hn:m:s:")) != EOF) { switch (dopt) { case 'h': usage(); return 0; case 'n': num_samples = atoi(optarg); break; case 'm': m = atoi(optarg); break; case 's': As = atof(optarg); break; default: exit(1); } } unsigned int i; // allocate arrays float complex x[2*num_samples]; // input array float complex y[ num_samples]; // output array // generate input unsigned int w_len = 2*num_samples - 4*m; // window length float beta = 8.0f; // kaiser window factor float w_sum = 0.0f; // gain due to window for (i=0; i<2*num_samples; i++) { // compute windowing function and keep track of gain float w = (i < w_len ? kaiser(i,w_len,beta,0) : 0.0f); w_sum += w; // compute windowed complex sinusoid x[i] = w * cexpf(_Complex_I*2*M_PI*fc*i); } // create/print the half-band resampler resamp2_crcf q = resamp2_crcf_create(m,0,As); resamp2_crcf_print(q); unsigned int delay = resamp2_crcf_get_delay(q); // run the resampler for (i=0; i<num_samples; i++) { // execute the decimator resamp2_crcf_decim_execute(q, &x[2*i], &y[i]); // print results to screen printf("y(%3u) = %8.4f + j*%8.4f;\n", i+1, crealf(y[i]), cimagf(y[i])); } // destroy half-band resampler resamp2_crcf_destroy(q); // // export results // FILE*fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\nclose all;\n\n"); fprintf(fid,"h_len=%u;\n", 4*m+1); fprintf(fid,"num_samples=%u;\n", num_samples); fprintf(fid,"delay =%u;\n", delay); fprintf(fid,"w_sum =%12.8f;\n", w_sum); for (i=0; i<num_samples; i++) { // save results to output file fprintf(fid,"x(%3u) = %12.8f + j*%12.8f;\n", 2*i+1, crealf(x[2*i+0]), cimagf(x[2*i+0])); fprintf(fid,"x(%3u) = %12.8f + j*%12.8f;\n", 2*i+2, crealf(x[2*i+1]), cimagf(x[2*i+1])); fprintf(fid,"y(%3u) = %12.8f + j*%12.8f;\n", i+1, 0.5f*crealf(y[i ]), 0.5f*cimagf(y[i ])); } // plot time series fprintf(fid,"tx = 0:(2*num_samples-1);\n"); fprintf(fid,"ty = [0:( num_samples-1)]*2 - delay;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," plot(tx,real(x),'-s','Color',[0.5 0.5 0.5],'MarkerSize',1,...\n"); fprintf(fid," ty,real(y),'-s','Color',[0.5 0.0 0.0],'MarkerSize',1);\n"); fprintf(fid," legend('original','decimated','location','northeast');"); fprintf(fid," axis([-delay 2*num_samples -1.2 1.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid," xlabel('Normalized Time [t/T_s]');\n"); fprintf(fid," ylabel('real');\n"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(tx,imag(x),'-s','Color',[0.5 0.5 0.5],'MarkerSize',1,...\n"); fprintf(fid," ty,imag(y),'-s','Color',[0.0 0.5 0.0],'MarkerSize',1);\n"); fprintf(fid," legend('original','decimated','location','northeast');"); fprintf(fid," axis([-delay 2*num_samples -1.2 1.2]);\n"); fprintf(fid," grid on;\n"); fprintf(fid," xlabel('Normalized Time [t/T_s]');\n"); fprintf(fid," ylabel('imag');\n"); // plot spectrum fprintf(fid,"nfft=512;\n"); fprintf(fid,"g = 1/w_sum;\n"); fprintf(fid,"X=20*log10(abs(fftshift(fft( x*g,nfft))));\n"); fprintf(fid,"Y=20*log10(abs(fftshift(fft(2*y*g,nfft))));\n"); fprintf(fid,"f=[0:(nfft-1)]/nfft-0.5;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(f, X,'LineWidth',1, 'Color',[0.5 0.5 0.5],...\n"); fprintf(fid," f/2,Y,'LineWidth',1.5,'Color',[0.1 0.3 0.5]);\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n"); fprintf(fid,"ylabel('PSD [dB]');\n"); fprintf(fid,"legend('original','decimated','location','northeast');"); fprintf(fid,"axis([-0.5 0.5 -100 10]);\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
// // AUTOTEST : test half-band filterbank (synthesizer) // void autotest_resamp2_synthesis() { unsigned int m=5; // filter semi-length (actual length: 4*m+1) unsigned int n=37; // number of input samples float As=60.0f; // stop-band attenuation [dB] float f0 = 0.0739f; // low frequency signal float f1 = -0.1387f; // high frequency signal (+pi) float tol = 3e-3f; // error tolerance unsigned int i; // allocate memory for data arrays float complex x0[n+2*m+1]; // input signal (with delay) float complex x1[n+2*m+1]; // input signal (with delay) float complex y[2*n]; // synthesized output // generate the baseband signals for (i=0; i<n+2*m+1; i++) { x0[i] = i < 2*n ? cexpf(_Complex_I*f0*i) : 0.0f; x1[i] = i < 2*n ? cexpf(_Complex_I*f1*i) : 0.0f; } // create/print the half-band resampler, with a specified // stopband attenuation level resamp2_crcf q = resamp2_crcf_create(m,0,As); // run synthesis float complex x_hat[2]; for (i=0; i<n; i++) { x_hat[0] = x0[i]; x_hat[1] = x1[i]; resamp2_crcf_synthesizer_execute(q, x_hat, &y[2*i]); } // clean up allocated objects resamp2_crcf_destroy(q); // validate output for (i=m; i<n-2*m; i++) { CONTEND_DELTA( crealf(y[i+2*m]), cosf(0.5f*f0*i) + cosf((M_PI+0.5f*f1)*i), tol ); CONTEND_DELTA( cimagf(y[i+2*m]), sinf(0.5f*f0*i) + sinf((M_PI+0.5f*f1)*i), tol ); } #if 0 // debugging FILE * fid = fopen("resamp2_test.m", "w"); fprintf(fid,"clear all\n"); fprintf(fid,"close all\n"); for (i=0; i<n+2*m+1; i++) { fprintf(fid,"x0(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x0[i]), cimagf(x0[i])); fprintf(fid,"x1(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x1[i]), cimagf(x1[i])); } for (i=0; i<2*n; i++) fprintf(fid,"y(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i])); // save expected values for (i=0; i<2*n; i++) { fprintf(fid,"z(%3u) = %12.4e + j*%12.4e;\n", i+1, cosf(i*0.5f*f0) + cosf(i*(M_PI+0.5f*f1)), sinf(i*0.5f*f0) + sinf(i*(M_PI+0.5f*f1))); } fprintf(fid,"m = %u;\n", m); fprintf(fid,"figure;\n"); fprintf(fid,"t = 0:(length(y)-1);\n"); fprintf(fid,"plot(t,real(z),t-2*m,real(y));\n"); fclose(fid); printf("results written to '%s'\n","resamp2_test.m"); #endif }
// // AUTOTEST : test half-band filterbank (analyzer) // void autotest_resamp2_analysis() { unsigned int m=5; // filter semi-length (actual length: 4*m+1) unsigned int n=37; // number of input samples float As=60.0f; // stop-band attenuation [dB] float f0 = 0.0739f; // low frequency signal float f1 = -0.1387f; // high frequency signal (+pi) float tol = 1e-3f; // error tolerance unsigned int i; // allocate memory for data arrays float complex x[2*n+2*m+1]; // input signal (with delay) float complex y0[n]; // low-pass output float complex y1[n]; // high-pass output // generate the baseband signal for (i=0; i<2*n+2*m+1; i++) x[i] = i < 2*n ? cexpf(_Complex_I*f0*i) + cexpf(_Complex_I*(M_PI+f1)*i) : 0.0f; // create/print the half-band resampler, with a specified // stopband attenuation level resamp2_crcf q = resamp2_crcf_create(m,0,As); // run half-band decimation float complex y_hat[2]; for (i=0; i<n; i++) { resamp2_crcf_analyzer_execute(q, &x[2*i], y_hat); y0[i] = y_hat[0]; y1[i] = y_hat[1]; } // clean up allocated objects resamp2_crcf_destroy(q); // validate output for (i=m; i<n-m; i++) { CONTEND_DELTA( crealf(y0[i+m]), cosf(2*f0*(i+0.5f)), tol ); CONTEND_DELTA( cimagf(y0[i+m]), sinf(2*f0*(i+0.5f)), tol ); CONTEND_DELTA( crealf(y1[i+m]), cosf(2*f1*(i+0.5f)), tol ); CONTEND_DELTA( cimagf(y1[i+m]), sinf(2*f1*(i+0.5f)), tol ); } #if 0 // debugging FILE * fid = fopen("resamp2_test.m", "w"); fprintf(fid,"clear all\n"); fprintf(fid,"close all\n"); for (i=0; i<2*n; i++) fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); for (i=0; i<n; i++) { fprintf(fid,"y0(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y0[i]), cimagf(y0[i])); fprintf(fid,"y1(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y1[i]), cimagf(y1[i])); } // save expected values for (i=0; i<n; i++) { fprintf(fid,"z0(%3u) = %12.4e + j*%12.4e;\n", i+1, cosf(i*2*f0), sinf(i*2*f0)); fprintf(fid,"z1(%3u) = %12.4e + j*%12.4e;\n", i+1, cosf(i*2*f1), sinf(i*2*f1)); } fprintf(fid,"m = %u;\n", m); fprintf(fid,"figure;\n"); fprintf(fid,"t = 0:(length(y0)-1);\n"); //fprintf(fid,"plot(t,real(z0),t-m+0.5,real(y0));\n"); fprintf(fid,"plot(t,real(z1),t-m+0.5,real(y1));\n"); fclose(fid); printf("results written to '%s'\n","resamp2_test.m"); #endif }
int main() { unsigned int m=9; // filter semi-length unsigned int num_samples=128; // number of input samples float As=60.0f; // stop-band attenuation [dB] // derived values unsigned int h_len = 4*m+1; // half-band filter length unsigned int N = num_samples + h_len; // ensure N is even N += (N%2); unsigned int n = N/2; // arrays float complex x[N]; // input time series float complex y[n][2]; // output time series (channelized) float complex z[N]; // output time series // generate input sequence unsigned int i; for (i=0; i<N; i++) { //x[i] = randnf() * cexpf(_Complex_I*M_PI*randf()); x[i] = cexpf(_Complex_I*2*M_PI*0.072f*i) + 0.6f*cexpf(_Complex_I*2*M_PI*0.37f*i); //x[i] = cexpf(_Complex_I*2*M_PI*0.072f*i); //x[i] += 0.6*cexpf(_Complex_I*2*M_PI*0.572f*i); x[i] *= (i < num_samples) ? hamming(i,num_samples) : 0.0f; } // create/print the half-band filter with a specified // stop-band attenuation resamp2_crcf q = resamp2_crcf_create(m,0.0f,As); resamp2_crcf_print(q); // run the resampler as a two-channel analysis filterbank for (i=0; i<n; i++) resamp2_crcf_analyzer_execute(q, &x[2*i], &y[i][0]); // clear resampler resamp2_crcf_clear(q); // run the resampler as a two-channel synthesis filterbank for (i=0; i<n; i++) resamp2_crcf_synthesizer_execute(q, &y[i][0], &z[2*i]); // clean up allocated objects resamp2_crcf_destroy(q); // // export output file // FILE*fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\nclose all;\n\n"); fprintf(fid,"m = %u;\n", m); fprintf(fid,"num_samples = %u;\n", num_samples); fprintf(fid,"N = %u;\n", N); // save results to output file for (i=0; i<n; i++) { fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", 2*i+1, crealf(x[2*i+0]), cimagf(x[2*i+0])); fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", 2*i+2, crealf(x[2*i+1]), cimagf(x[2*i+1])); fprintf(fid,"y0(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i][0]), cimagf(y[i][0])); fprintf(fid,"y1(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i][1]), cimagf(y[i][1])); fprintf(fid,"z(%3u) = %12.4e + j*%12.4e;\n", 2*i+1, crealf(z[2*i+0]), cimagf(z[2*i+0])); fprintf(fid,"z(%3u) = %12.4e + j*%12.4e;\n", 2*i+2, crealf(z[2*i+1]), cimagf(z[2*i+1])); } fprintf(fid,"tx = 0:(N-1);\n"); fprintf(fid,"ty = tx(1:2:end);\n"); fprintf(fid,"tz = tx - 4*m + 1;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," plot(tx, real(x), 'LineWidth',1,'Color',[0.50 0.50 0.50],...\n"); fprintf(fid," tz, real(z), 'LineWidth',1,'Color',[0.00 0.25 0.50]);\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('real');\n"); fprintf(fid," legend('original','reconstructed',1);"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(tx, imag(x), 'LineWidth',1,'Color',[0.50 0.50 0.50],...\n"); fprintf(fid," tz, imag(z), 'LineWidth',1,'Color',[0.00 0.50 0.25]);\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('imag');\n"); fprintf(fid," legend('original','reconstructed',1);"); fprintf(fid,"nfft=512;\n"); fprintf(fid,"g = 1 / sqrt( real(x*x') );\n"); fprintf(fid,"X =20*log10(abs(fftshift(fft(x*g, nfft))));\n"); fprintf(fid,"Y0=20*log10(abs(fftshift(fft(y0*g,nfft))));\n"); fprintf(fid,"Y1=20*log10(abs(fftshift(fft(y1*g,nfft))));\n"); fprintf(fid,"Z =20*log10(abs(fftshift(fft(z*g, nfft))));\n"); fprintf(fid,"f=[0:(nfft-1)]/nfft-0.5;\n"); fprintf(fid,"figure;\n"); fprintf(fid,"plot(f,X, 'LineWidth',2,'Color',[0.50 0.50 0.50],...\n"); fprintf(fid," f,Z, 'LineWidth',1,'Color',[0.00 0.25 0.50]);\n"); //fprintf(fid," f,Y0,'LineWidth',1,'Color',[0.00 0.25 0.50],...\n"); //fprintf(fid," f,Y1,'LineWidth',1,'Color',[0.00 0.50 0.25]);\n"); fprintf(fid,"grid on;\n"); fprintf(fid,"xlabel('normalized frequency');\n"); fprintf(fid,"ylabel('PSD [dB]');\n"); fprintf(fid,"legend('original','reconstructed',2);"); fprintf(fid,"axis([-0.5 0.5 -80 20]);\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }