// create spgram object // _nfft : FFT size // _wtype : window type, e.g. LIQUID_WINDOW_HAMMING // _window_len : window length // _delay : delay between transforms, _delay > 0 SPGRAM() SPGRAM(_create)(unsigned int _nfft, int _wtype, unsigned int _window_len, unsigned int _delay) { // validate input if (_nfft < 2) { fprintf(stderr,"error: spgram%s_create(), fft size must be at least 2\n", EXTENSION); exit(1); } else if (_window_len > _nfft) { fprintf(stderr,"error: spgram%s_create(), window size cannot exceed fft size\n", EXTENSION); exit(1); } else if (_window_len == 0) { fprintf(stderr,"error: spgram%s_create(), window size must be greater than zero\n", EXTENSION); exit(1); } else if (_wtype == LIQUID_WINDOW_KBD && _window_len % 2) { fprintf(stderr,"error: spgram%s_create(), KBD window length must be even\n", EXTENSION); exit(1); } else if (_delay == 0) { fprintf(stderr,"error: spgram%s_create(), delay must be greater than 0\n", EXTENSION); exit(1); } // allocate memory for main object SPGRAM() q = (SPGRAM()) malloc(sizeof(struct SPGRAM(_s))); // set input parameters q->nfft = _nfft; q->wtype = _wtype; q->window_len = _window_len; q->delay = _delay; q->frequency = 0; q->sample_rate= -1; // set object for full accumulation SPGRAM(_set_alpha)(q, -1.0f); // create FFT arrays, object q->buf_time = (TC*) malloc((q->nfft)*sizeof(TC)); q->buf_freq = (TC*) malloc((q->nfft)*sizeof(TC)); q->psd = (T *) malloc((q->nfft)*sizeof(T )); q->fft = FFT_CREATE_PLAN(q->nfft, q->buf_time, q->buf_freq, FFT_DIR_FORWARD, FFT_METHOD); // create buffer q->buffer = WINDOW(_create)(q->window_len); // create window q->w = (T*) malloc((q->window_len)*sizeof(T)); unsigned int i; unsigned int n = q->window_len; float beta = 10.0f; float zeta = 3.0f; for (i=0; i<n; i++) { switch (q->wtype) { case LIQUID_WINDOW_HAMMING: q->w[i] = hamming(i,n); break; case LIQUID_WINDOW_HANN: q->w[i] = hann(i,n); break; case LIQUID_WINDOW_BLACKMANHARRIS: q->w[i] = blackmanharris(i,n); break; case LIQUID_WINDOW_BLACKMANHARRIS7: q->w[i] = blackmanharris7(i,n); break; case LIQUID_WINDOW_KAISER: q->w[i] = kaiser(i,n,beta,0); break; case LIQUID_WINDOW_FLATTOP: q->w[i] = flattop(i,n); break; case LIQUID_WINDOW_TRIANGULAR: q->w[i] = triangular(i,n,n); break; case LIQUID_WINDOW_RCOSTAPER: q->w[i] = liquid_rcostaper_windowf(i,n/3,n); break; case LIQUID_WINDOW_KBD: q->w[i] = liquid_kbd(i,n,zeta); break; default: fprintf(stderr,"error: spgram%s_create(), invalid window\n", EXTENSION); exit(1); } } // scale by window magnitude, FFT size float g = 0.0f; for (i=0; i<q->window_len; i++) g += q->w[i] * q->w[i]; g = M_SQRT2 / ( sqrtf(g / q->window_len) * sqrtf((float)(q->nfft)) ); // scale window and copy for (i=0; i<q->window_len; i++) q->w[i] = g * q->w[i]; // reset the spgram object q->num_samples_total = 0; q->num_transforms_total = 0; SPGRAM(_reset)(q); // return new object return q; }
int main() { // options unsigned int h_len = 7; // filter semi-length (filter delay) float r=1/sqrtf(2); // resampling rate (output/input) float bw=0.25f; // resampling filter bandwidth float As=60.0f; // resampling filter stop-band attenuation [dB] unsigned int npfb=32; // number of filters in bank (timing resolution) unsigned int n=180; // number of input samples // number of input samples (adjusted for filter delay) unsigned int nx = n + h_len; // generate input sequence : windowed sum of complex sinusoids unsigned int i; float complex x[nx]; for (i=0; i<nx; i++) { float complex jphi = _Complex_I*2.0f*M_PI*i; x[i] = cexpf(jphi*0.02f) + 1.4f*cexpf(jphi*0.07f); // window edge size unsigned int t = (unsigned int)(0.1*n); if (i < n) { // edge-rounded window if (i < t) x[i] *= blackmanharris(i,2*t); else if (i >= n-t) x[i] *= blackmanharris(n-i-1,2*t); } else { x[i] = 0.; } } // output buffer with extra padding for good measure unsigned int y_len = (unsigned int) ceilf(1.1*r*nx) + 16; float complex y[y_len]; // create resampler resamp_crcf f = resamp_crcf_create(r,h_len,bw,As,npfb); unsigned int num_written; unsigned int ny=0; for (i=0; i<nx; i++) { // execute resampler, storing in output buffer resamp_crcf_execute(f, x[i], &y[ny], &num_written); ny += num_written; } printf(" %u / %u\n", ny, nx); // clean up allocated objects resamp_crcf_destroy(f); // open/initialize output file FILE*fid = fopen(OUTPUT_FILENAME_TIME,"w"); fprintf(fid,"# %s: auto-generated file\n\n", OUTPUT_FILENAME_TIME); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); //fprintf(fid,"set xrange [0:%u];\n",n); fprintf(fid,"set yrange [-3:3]\n"); fprintf(fid,"set size ratio 0.3\n"); fprintf(fid,"set xlabel 'Input Sample Index'\n"); fprintf(fid,"set key top right nobox\n"); fprintf(fid,"set ytics -5,1,5\n"); fprintf(fid,"set grid xtics ytics\n"); fprintf(fid,"set pointsize 0.6\n"); fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n", LIQUID_DOC_COLOR_GRID); fprintf(fid,"set multiplot layout 2,1 scale 1.0,1.0\n"); fprintf(fid,"# real\n"); fprintf(fid,"set ylabel 'Real'\n"); fprintf(fid,"plot '-' using 1:2 with linespoints pointtype 7 linetype 1 linewidth 1 linecolor rgb '#999999' title 'original',\\\n"); fprintf(fid," '-' using 1:2 with points pointtype 7 linecolor rgb '#008000' title 'resampled'\n"); // export output for (i=0; i<nx; i++) { //fprintf(fid,"%6u %12.4e %12.4e\n", i, cos(2*M_PI*0.04*i), sin(2*M_PI*0.04*i)); fprintf(fid,"%6u %12.4e %12.4e\n", i, crealf(x[i]), cimagf(x[i])); } fprintf(fid,"e\n"); float t; for (i=0; i<ny; i++) { t = (float)(i) / r - (float)(h_len); fprintf(fid,"%12.4e %12.4e %12.4e\n", t, crealf(y[i]), cimagf(y[i])); } fprintf(fid,"e\n"); fprintf(fid,"# imag\n"); fprintf(fid,"set ylabel 'Imag'\n"); fprintf(fid,"plot '-' using 1:3 with linespoints pointtype 7 linetype 1 linewidth 1 linecolor rgb '#999999' title 'original',\\\n"); fprintf(fid," '-' using 1:3 with points pointtype 7 linecolor rgb '#800000' title 'resampled'\n"); // export output for (i=0; i<nx; i++) { //fprintf(fid,"%6u %12.4e %12.4e\n", i, cos(2*M_PI*0.04*i), sin(2*M_PI*0.04*i)); fprintf(fid,"%6u %12.4e %12.4e\n", i, crealf(x[i]), cimagf(x[i])); } fprintf(fid,"e\n"); for (i=0; i<ny; i++) { t = (float)(i) / r - (float)(h_len); fprintf(fid,"%12.4e %12.4e %12.4e\n", t, crealf(y[i]), cimagf(y[i])); } fprintf(fid,"e\n"); fprintf(fid,"unset multiplot\n"); // close output file fclose(fid); fid = fopen(OUTPUT_FILENAME_FREQ,"w"); unsigned int nfft = 512; float complex X[nfft]; float complex Y[nfft]; liquid_doc_compute_psdcf(x,nx,X,nfft,LIQUID_DOC_PSDWINDOW_HANN,0); liquid_doc_compute_psdcf(y,ny,Y,nfft,LIQUID_DOC_PSDWINDOW_HANN,0); fft_shift(X,nfft); fft_shift(Y,nfft); float scaling_factor = 20*log10f(nfft); fprintf(fid,"# %s: auto-generated file\n\n", OUTPUT_FILENAME_FREQ); fprintf(fid,"reset\n"); fprintf(fid,"set terminal postscript eps enhanced color solid rounded\n"); fprintf(fid,"set xrange [-0.5:0.5];\n"); fprintf(fid,"set yrange [-120:20]\n"); fprintf(fid,"set size ratio 0.6\n"); fprintf(fid,"set xlabel 'Normalized Input Frequency'\n"); fprintf(fid,"set ylabel 'Power Spectral Density [dB]'\n"); fprintf(fid,"set key top right nobox\n"); fprintf(fid,"set grid xtics ytics\n"); fprintf(fid,"set pointsize 0.6\n"); fprintf(fid,"set grid linetype 1 linecolor rgb '%s' lw 1\n",LIQUID_DOC_COLOR_GRID); fprintf(fid,"# real\n"); fprintf(fid,"plot '-' using 1:2 with lines linetype 1 linewidth 4 linecolor rgb '#999999' title 'original',\\\n"); fprintf(fid," '-' using 1:2 with lines linetype 1 linewidth 4 linecolor rgb '#004080' title 'resampled'\n"); // export output for (i=0; i<nfft; i++) { float fx = (float)(i) / (float)nfft - 0.5f; fprintf(fid,"%12.8f %12.4e\n", fx, 20*log10f(cabsf(X[i])) - scaling_factor); } fprintf(fid,"e\n"); for (i=0; i<nfft; i++) { float fy = ((float)(i) / (float)nfft - 0.5f)*r; fprintf(fid,"%12.8f %12.4e\n", fy, 20*log10f(cabsf(Y[i])) - scaling_factor - 20*log10(r)); } fprintf(fid,"e\n"); fclose(fid); printf("done.\n"); return 0; }