コード例 #1
0
ファイル: spgram.c プロジェクト: jgaeddert/liquid-dsp
// 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;
}
コード例 #2
0
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;
}