// // 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 }
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; }