コード例 #1
0
ファイル: flexframesync.c プロジェクト: Clivia/liquid-dsp
// create flexframesync object
//  _callback       :   callback function invoked when frame is received
//  _userdata       :   user-defined data object passed to callback
flexframesync flexframesync_create(framesync_callback _callback,
                                   void *             _userdata)
{
    flexframesync q = (flexframesync) malloc(sizeof(struct flexframesync_s));
    q->callback = _callback;
    q->userdata = _userdata;

    unsigned int i;

    // generate p/n sequence
    msequence ms = msequence_create(6, 0x005b, 1);
    for (i=0; i<64; i++)
        q->preamble_pn[i] = (msequence_advance(ms)) ? 1.0f : -1.0f;
    msequence_destroy(ms);

    // interpolate p/n sequence with matched filter
    q->k    = 2;        // samples/symbol
    q->m    = 7;        // filter delay (symbols)
    q->beta = 0.25f;    // excess bandwidth factor
    float complex seq[q->k*64];
    firinterp_crcf interp = firinterp_crcf_create_rnyquist(LIQUID_FIRFILT_ARKAISER,q->k,q->m,q->beta,0);
    for (i=0; i<64+q->m; i++) {
        // compensate for filter delay
        if (i < q->m) firinterp_crcf_execute(interp, q->preamble_pn[i],    &seq[0]);
        else          firinterp_crcf_execute(interp, q->preamble_pn[i%64], &seq[q->k*(i-q->m)]);
    }
    firinterp_crcf_destroy(interp);

    // create frame detector
    float threshold = 0.4f;     // detection threshold
    float dphi_max  = 0.05f;    // maximum carrier offset allowable
    q->frame_detector = detector_cccf_create(seq, q->k*64, threshold, dphi_max);
    q->buffer = windowcf_create(q->k*(64+q->m));

    // create symbol timing recovery filters
    q->npfb = 32;   // number of filters in the bank
    q->mf   = firpfb_crcf_create_rnyquist(LIQUID_FIRFILT_ARKAISER, q->npfb,q->k,q->m,q->beta);
    q->dmf  = firpfb_crcf_create_drnyquist(LIQUID_FIRFILT_ARKAISER,q->npfb,q->k,q->m,q->beta);

    // create down-coverters for carrier phase tracking
    q->nco_coarse = nco_crcf_create(LIQUID_NCO);
    q->nco_fine   = nco_crcf_create(LIQUID_VCO);
    nco_crcf_pll_set_bandwidth(q->nco_fine, 0.05f);
    
    // create header objects
    q->demod_header = modem_create(LIQUID_MODEM_BPSK);
    q->p_header   = packetizer_create(FLEXFRAME_H_DEC,
                                      FLEXFRAME_H_CRC,
                                      FLEXFRAME_H_FEC0,
                                      FLEXFRAME_H_FEC1);
    assert(packetizer_get_enc_msg_len(q->p_header)==FLEXFRAME_H_ENC);

    // frame properties (default values to be overwritten when frame
    // header is received and properly decoded)
    q->ms_payload      = LIQUID_MODEM_QPSK;
    q->bps_payload     = 2;
    q->payload_dec_len = 1;
    q->check           = LIQUID_CRC_NONE;
    q->fec0            = LIQUID_FEC_NONE;
    q->fec1            = LIQUID_FEC_NONE;

    // create payload objects (overridden by received properties)
    q->demod_payload   = modem_create(LIQUID_MODEM_QPSK);
    q->p_payload       = packetizer_create(q->payload_dec_len, q->check, q->fec0, q->fec1);
    q->payload_enc_len = packetizer_get_enc_msg_len(q->p_payload);
    q->payload_mod_len = 4 * q->payload_enc_len;
    q->payload_mod     = (unsigned char*) malloc(q->payload_mod_len*sizeof(unsigned char));
    q->payload_enc     = (unsigned char*) malloc(q->payload_enc_len*sizeof(unsigned char));
    q->payload_dec     = (unsigned char*) malloc(q->payload_dec_len*sizeof(unsigned char));

#if DEBUG_FLEXFRAMESYNC
    // set debugging flags, objects to NULL
    q->debug_enabled         = 0;
    q->debug_objects_created = 0;
    q->debug_x               = NULL;
#endif

    // reset state
    flexframesync_reset(q);

    return q;
}
コード例 #2
0
ファイル: predemod_sync_test.c プロジェクト: GRDSP/grdsp
int main(int argc, char*argv[])
{
    srand(time(NULL));
    // options
    unsigned int k=2;                   // filter samples/symbol
    unsigned int m=4;                   // filter delay (symbols)
    float beta=0.3f;                    // bandwidth-time product
    float dt = 0.0f;                    // fractional sample timing offset
    unsigned int num_sync_symbols = 64; // number of data symbols
    float SNRdB = 30.0f;                // signal-to-noise ratio [dB]
    float dphi = 0.0f;                  // carrier frequency offset
    float phi  = 0.0f;                  // carrier phase offset
    
    unsigned int num_delay_symbols = 12;
    unsigned int num_dphi_hat = 21;     // number of frequency offset estimates
    float dphi_hat_step = 0.01f;        // frequency offset step size

    int dopt;
    while ((dopt = getopt(argc,argv,"uhk:m:n:b:t:F:P:s:")) != EOF) {
        switch (dopt) {
        case 'h': usage();              return 0;
        case 'k': k     = atoi(optarg); break;
        case 'm': m     = atoi(optarg); break;
        case 'n': num_sync_symbols = atoi(optarg); break;
        case 'b': beta  = atof(optarg); break;
        case 't': dt    = atof(optarg); break;
        case 'F': dphi  = atof(optarg); break;
        case 'P': phi   = atof(optarg); break;
        case 's': SNRdB = atof(optarg); break;
        default:
            exit(1);
        }
    }

    unsigned int i;

    // validate input
    if (beta <= 0.0f || beta >= 1.0f) {
        fprintf(stderr,"error: %s, bandwidth-time product must be in (0,1)\n", argv[0]);
        exit(1);
    } else if (dt < -0.5 || dt > 0.5) {
        fprintf(stderr,"error: %s, fractional sample offset must be in (0,1)\n", argv[0]);
        exit(1);
    }

    // derived values
    unsigned int num_symbols = num_delay_symbols + num_sync_symbols + 2*m;
    unsigned int num_samples = k*num_symbols;
    unsigned int num_sync_samples = k*num_sync_symbols;
    float nstd = powf(10.0f, -SNRdB/20.0f);

    // arrays
    float complex seq[num_sync_symbols];    // data sequence (symbols)
    float complex s0[num_sync_samples];     // data sequence (interpolated samples)
    float complex x[num_samples];           // transmitted signal
    float complex y[num_samples];           // received signal
    float rxy[num_dphi_hat][num_samples];   // pre-demod output matrix

    // generate sequence
    for (i=0; i<num_sync_symbols; i++) {
        float sym_i = rand() % 2 ? M_SQRT1_2 : -M_SQRT1_2;
        float sym_q = rand() % 2 ? M_SQRT1_2 : -M_SQRT1_2;
        seq[i] = sym_i + _Complex_I*sym_q;
    }

    // create interpolated sequence, compensating for filter delay
    firinterp_crcf interp_seq = firinterp_crcf_create_rnyquist(LIQUID_RNYQUIST_RRC,k,m,beta,0.0f);
    for (i=0; i<num_sync_symbols+m; i++) {
        if      (i < m)                firinterp_crcf_execute(interp_seq, seq[i], &s0[0]);
        else if (i < num_sync_symbols) firinterp_crcf_execute(interp_seq, seq[i], &s0[k*(i-m)]);
        else                           firinterp_crcf_execute(interp_seq,      0, &s0[k*(i-m)]);
    }
    firinterp_crcf_destroy(interp_seq);
    
    // compute g = E{ |s0|^2 }
    float g = 0.0f;
    for (i=0; i<num_sync_samples; i++)
        g += crealf( s0[i]*conjf(s0[i]) );

    // create transmit interpolator and generate sequence
    firinterp_crcf interp_tx = firinterp_crcf_create_rnyquist(LIQUID_RNYQUIST_RRC,k,m,beta,dt);
    unsigned int n=0;
    for (i=0; i<num_delay_symbols; i++) {
        firinterp_crcf_execute(interp_tx, 0, &x[k*n]);
        n++;
    }
    for (i=0; i<num_sync_symbols; i++) {
        firinterp_crcf_execute(interp_tx, seq[i], &x[k*n]);
        n++;
    }
    for (i=0; i<2*m; i++) {
        firinterp_crcf_execute(interp_tx, 0, &x[k*n]);
        n++;
    }
    assert(n==num_symbols);
    firinterp_crcf_destroy(interp_tx);

    // add channel impairments
    for (i=0; i<num_samples; i++) {
        y[i] = x[i]*cexp(_Complex_I*(dphi*i + phi)) + nstd*( randnf() + _Complex_I*randnf() );
    }

    float complex z;    // filter output sample
    for (n=0; n<num_dphi_hat; n++) {
        float dphi_hat = ((float)n - 0.5*(float)(num_dphi_hat-1)) * dphi_hat_step;
        printf("  dphi_hat : %12.8f\n", dphi_hat);

        // create flipped, conjugated coefficients
        float complex s1[num_sync_samples];
        for (i=0; i<num_sync_samples; i++)
            s1[i] = conjf( s0[num_sync_samples-i-1]*cexpf(_Complex_I*(dphi_hat*i)) );

        // create matched filter and detect signal
        firfilt_cccf fsync = firfilt_cccf_create(s1, num_sync_samples);
        for (i=0; i<num_samples; i++) {
            firfilt_cccf_push(fsync, y[i]);
            firfilt_cccf_execute(fsync, &z);

            rxy[n][i] = cabsf(z) / g;
        }
        // destroy filter
        firfilt_cccf_destroy(fsync);
    }
    
    // print results
    //printf("rxy (max) : %12.8f\n", rxy_max);

    // 
    // export results
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all\n");
    fprintf(fid,"close all\n");
    fprintf(fid,"k = %u;\n", k);
    fprintf(fid,"m = %u;\n", m);
    fprintf(fid,"beta = %f;\n", beta);
    fprintf(fid,"num_sync_symbols = %u;\n", num_sync_symbols);
    fprintf(fid,"num_sync_samples = k*num_sync_symbols;\n");
    fprintf(fid,"num_symbols = %u;\n", num_symbols);
    fprintf(fid,"num_samples = %u;\n", num_samples);
    fprintf(fid,"num_dphi_hat = %u;\n", num_dphi_hat);
    fprintf(fid,"dphi_hat_step = %f;\n", dphi_hat_step);

    // save sequence symbols
    fprintf(fid,"seq = zeros(1,num_sync_symbols);\n");
    for (i=0; i<num_sync_symbols; i++)
        fprintf(fid,"seq(%4u)   = %12.8f + j*%12.8f;\n", i+1, crealf(seq[i]), cimagf(seq[i]));

    // save interpolated sequence
    fprintf(fid,"s   = zeros(1,num_sync_samples);\n");
    for (i=0; i<num_sync_samples; i++)
        fprintf(fid,"s(%4u)     = %12.8f + j*%12.8f;\n", i+1, crealf(s0[i]), cimagf(s0[i]));

    fprintf(fid,"x = zeros(1,num_samples);\n");
    fprintf(fid,"y = zeros(1,num_samples);\n");
    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%6u) = %12.8f + j*%12.8f;\n", i+1, crealf(x[i]),   cimagf(x[i]));
        fprintf(fid,"y(%6u) = %12.8f + j*%12.8f;\n", i+1, crealf(y[i]),   cimagf(y[i]));
    }

    // save cross-correlation output
    fprintf(fid,"rxy = zeros(num_dphi_hat,num_samples);\n");
    for (n=0; n<num_dphi_hat; n++) {
        for (i=0; i<num_samples; i++) {
            fprintf(fid,"rxy(%6u,%6u) = %12.8f;\n", n+1, i+1, rxy[n][i]);
        }
    }
    fprintf(fid,"t=[0:(num_samples-1)]/k;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(1:length(s),real(s), 1:length(s),imag(s));\n");
    
    fprintf(fid,"dphi_hat = ( [0:(num_dphi_hat-1)] - (num_dphi_hat-1)/2 ) * dphi_hat_step;\n");
    fprintf(fid,"mesh(dphi_hat, t, rxy');\n");
    
#if 0
    fprintf(fid,"z = abs( z );\n");
    fprintf(fid,"[zmax i] = max(z);\n");
    fprintf(fid,"plot(1:length(z),z,'-x');\n");
    fprintf(fid,"axis([(i-8*k) (i+8*k) 0 zmax*1.2]);\n");
    fprintf(fid,"grid on\n");
#endif

    fclose(fid);
    printf("results written to '%s'\n", OUTPUT_FILENAME);

    return 0;
}
コード例 #3
0
ファイル: spgram_example.c プロジェクト: Sangstbk/liquid-dsp
int main() {
    // spectral periodogram options
    unsigned int nfft=512;              // spectral periodogram FFT size
    unsigned int num_samples = 4000;    // number of samples
    float beta = 10.0f;                 // Kaiser-Bessel window parameter
    float noise_floor = -60.0f;         // noise floor [dB]

    unsigned int i;

    // derived values
    float nstd = powf(10.0f, noise_floor/20.0f);

    // allocate memory for data arrays
    float complex X[nfft];              // output spectrum
    float psd[nfft];                    // power spectral density

    // initialize PSD estimate
    for (i=0; i<nfft; i++)
        psd[i] = 0.0f;

    // create spectral periodogram
    unsigned int window_size = nfft/2;  // spgram window size
    unsigned int delay       = nfft/8;  // samples between transforms
    spgram q = spgram_create_kaiser(nfft, window_size, beta);

    // generate signal (interpolated symbols with noise)
    unsigned int k = 4;     // interpolation rate
    unsigned int m = 7;     // filter delay (symbols)
    firinterp_crcf interp = firinterp_crcf_create_rnyquist(LIQUID_RNYQUIST_RKAISER, k, m, 0.3f, 0.0f);

    int spgram_timer = nfft;
    unsigned int n=0;
    float complex x[k]; // interpolator output
    unsigned int num_transforms = 0;
    while (n < num_samples) {
        // generate random symbol
        float complex s = ( rand() % 2 ? 0.707f : -0.707f ) +
                          ( rand() % 2 ? 0.707f : -0.707f ) * _Complex_I;

        // interpolate
        firinterp_crcf_execute(interp, s, x);

        // add noise
        for (i=0; i<k; i++)
            x[i] += nstd * ( randnf() + _Complex_I*randnf() ) * M_SQRT1_2;

        // push resulting samples through spgram
        spgram_push(q, x, k);

        // 
        spgram_timer -= k;
        n += k;

        //
        if (spgram_timer <= 0) {
            // update timer, counter
            spgram_timer += delay;
            num_transforms++;

            // run spectral periodogram
            spgram_execute(q, X);

            // accumulate PSD and FFT shift
            for (i=0; i<nfft; i++) {
                float complex X0 = X[(i+nfft/2)%nfft];
                psd[i] += crealf(X0*conjf(X0));
            }
        }
    }

    // destroy objects
    firinterp_crcf_destroy(interp);
    spgram_destroy(q);

    // normalize result
    printf("computed %u transforms\n", num_transforms);
    // TODO: ensure at least one transform was taken
    for (i=0; i<nfft; i++)
        psd[i] = 10*log10f( psd[i] / (float)(num_transforms) );

    // 
    // export output file
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n\n");
    fprintf(fid,"nfft = %u;\n", nfft);
    fprintf(fid,"f    = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"H    = zeros(1,nfft);\n");
    fprintf(fid,"noise_floor = %12.6f;\n", noise_floor);
    
    for (i=0; i<nfft; i++)
        fprintf(fid,"H(%6u) = %12.4e;\n", i+1, psd[i]);

    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(f, H, '-', 'LineWidth',1.5);\n");
    fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
    fprintf(fid,"ylabel('Power Spectral Density [dB]');\n");
    fprintf(fid,"grid on;\n");
    fprintf(fid,"ymin = 10*floor([noise_floor-20]/10);\n");
    fprintf(fid,"ymax = 10*floor([noise_floor+80]/10);\n");
    fprintf(fid,"axis([-0.5 0.5 ymin ymax]);\n");

    fclose(fid);
    printf("results written to %s.\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}