示例#1
0
void ampmodem_modulate(ampmodem _q,
                       float _x,
                       float complex *_y)
{
    float complex x_hat = 0.0f;
    float complex y_hat;

    if (_q->type == LIQUID_AMPMODEM_DSB) {
        x_hat = _x;
    } else {
        // push through Hilbert transform
        // LIQUID_AMPMODEM_USB:
        // LIQUID_AMPMODEM_LSB: conjugate Hilbert transform output
        firhilbf_r2c_execute(_q->hilbert, _x, &x_hat);

        if (_q->type == LIQUID_AMPMODEM_LSB)
            x_hat = conjf(x_hat);
    }

    if (_q->suppressed_carrier)
        y_hat = x_hat;
    else
        y_hat = 0.5f*(x_hat + 1.0f);
    
    // mix up
    nco_crcf_mix_up(_q->oscillator, y_hat, _y);
    nco_crcf_step(_q->oscillator);
}
示例#2
0
int main()
{
    // spectral periodogram options
    unsigned int nfft        =   1200;  // spectral periodogram FFT size
    unsigned int num_samples =  64000;  // number of samples
    float        fc          =   0.20f; // carrier (relative to sampling rate)

    // create objects
    iirfilt_crcf   filter_tx    = iirfilt_crcf_create_lowpass(15, 0.05);
    nco_crcf       mixer_tx     = nco_crcf_create(LIQUID_VCO);
    nco_crcf       mixer_rx     = nco_crcf_create(LIQUID_VCO);
    iirfilt_crcf   filter_rx    = iirfilt_crcf_create_lowpass(7, 0.2);

    // set carrier frequencies
    nco_crcf_set_frequency(mixer_tx, fc * 2*M_PI);
    nco_crcf_set_frequency(mixer_rx, fc * 2*M_PI);

    // create objects for measuring power spectral density
    spgramcf spgram_tx  = spgramcf_create_default(nfft);
    spgramf  spgram_dac = spgramf_create_default(nfft);
    spgramcf spgram_rx  = spgramcf_create_default(nfft);

    // run through loop one step at a time
    unsigned int i;
    for (i=0; i<num_samples; i++) {
        // STEP 1: generate input signal (filtered noise with offset tone)
        float complex v1 = (randnf() + randnf()*_Complex_I) + 3.0f*cexpf(-_Complex_I*0.2f*i);
        iirfilt_crcf_execute(filter_tx, v1, &v1);

        // save spectrum
        spgramcf_push(spgram_tx, v1);

        // STEP 2: mix signal up and save real part (DAC output)
        nco_crcf_mix_up(mixer_tx, v1, &v1);
        float v2 = crealf(v1);
        nco_crcf_step(mixer_tx);

        // save spectrum
        spgramf_push(spgram_dac, v2);

        // STEP 3: mix signal down and filter off image
        float complex v3;
        nco_crcf_mix_down(mixer_rx, v2, &v3);
        iirfilt_crcf_execute(filter_rx, v3, &v3);
        nco_crcf_step(mixer_rx);

        // save spectrum
        spgramcf_push(spgram_rx, v3);
    }

    // compute power spectral density output
    float   psd_tx  [nfft];
    float   psd_dac [nfft];
    float   psd_rx  [nfft];
    spgramcf_get_psd(spgram_tx,  psd_tx);
    spgramf_get_psd( spgram_dac, psd_dac);
    spgramcf_get_psd(spgram_rx,  psd_rx);

    // destroy objects
    spgramcf_destroy(spgram_tx);
    spgramf_destroy(spgram_dac);
    spgramcf_destroy(spgram_rx);

    iirfilt_crcf_destroy(filter_tx);
    nco_crcf_destroy(mixer_tx);
    nco_crcf_destroy(mixer_rx);
    iirfilt_crcf_destroy(filter_rx);

    // 
    // 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,"psd_tx = zeros(1,nfft);\n");
    fprintf(fid,"psd_dac= zeros(1,nfft);\n");
    fprintf(fid,"psd_rx = zeros(1,nfft);\n");
    
    for (i=0; i<nfft; i++) {
        fprintf(fid,"psd_tx (%6u) = %12.4e;\n", i+1, psd_tx [i]);
        fprintf(fid,"psd_dac(%6u) = %12.4e;\n", i+1, psd_dac[i]);
        fprintf(fid,"psd_rx (%6u) = %12.4e;\n", i+1, psd_rx [i]);
    }

    fprintf(fid,"figure;\n");
    fprintf(fid,"hold on;\n");
    fprintf(fid,"  plot(f, psd_tx,  '-', 'LineWidth',1.5,'Color',[0.7 0.7 0.7]);\n");
    fprintf(fid,"  plot(f, psd_dac, '-', 'LineWidth',1.5,'Color',[0.0 0.5 0.3]);\n");
    fprintf(fid,"  plot(f, psd_rx,  '-', 'LineWidth',1.5,'Color',[0.0 0.3 0.5]);\n");
    fprintf(fid,"hold off;\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,"axis([-0.5 0.5 -100 60]);\n");
    fprintf(fid,"legend('transmit (complex)','DAC output (real)','receive (complex)','location','northeast');\n");

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

    printf("done.\n");
    return 0;
}
示例#3
0
int main(int argc, char*argv[]) {
    srand( time(NULL) );
    // parameters
    float phase_offset = M_PI/10;
    float frequency_offset = 0.001f;
    float SNRdB = 30.0f;
    float pll_bandwidth = 0.02f;
    modulation_scheme ms = LIQUID_MODEM_QPSK;
    unsigned int n=256;     // number of iterations

    int dopt;
    while ((dopt = getopt(argc,argv,"uhs:b:n:P:F:m:")) != EOF) {
        switch (dopt) {
        case 'u':
        case 'h':   usage();    return 0;
        case 's':   SNRdB = atof(optarg);           break;
        case 'b':   pll_bandwidth = atof(optarg);   break;
        case 'n':   n = atoi(optarg);               break;
        case 'P':   phase_offset = atof(optarg);    break;
        case 'F':   frequency_offset= atof(optarg); break;
        case 'm':
            ms = liquid_getopt_str2mod(optarg);
            if (ms == LIQUID_MODEM_UNKNOWN) {
                fprintf(stderr,"error: %s, unknown/unsupported modulation scheme \"%s\"\n", argv[0], optarg);
                return 1;
            }
            break;
        default:
            exit(1);
        }
    }
    unsigned int d=n/32;      // print every "d" lines

    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid, "%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid, "clear all;\n");
    fprintf(fid, "phi=zeros(1,%u);\n",n);
    fprintf(fid, "r=zeros(1,%u);\n",n);

    // objects
    nco_crcf nco_tx = nco_crcf_create(LIQUID_VCO);
    nco_crcf nco_rx = nco_crcf_create(LIQUID_VCO);

    modem mod   = modem_create(ms);
    modem demod = modem_create(ms);

    unsigned int bps = modem_get_bps(mod);

    // initialize objects
    nco_crcf_set_phase(nco_tx, phase_offset);
    nco_crcf_set_frequency(nco_tx, frequency_offset);
    nco_crcf_pll_set_bandwidth(nco_rx, pll_bandwidth);

    float noise_power = powf(10.0f, -SNRdB/20.0f);

    // print parameters
    printf("PLL example :\n");
    printf("modem : %u-%s\n", 1<<bps, modulation_types[ms].name);
    printf("frequency offset: %6.3f, phase offset: %6.3f, SNR: %6.2fdB, pll b/w: %6.3f\n",
            frequency_offset, phase_offset, SNRdB, pll_bandwidth);

    // run loop
    unsigned int i, M=1<<bps, sym_in, sym_out, num_errors=0;
    float phase_error;
    float complex x, r, v, noise;
    for (i=0; i<n; i++) {
        // generate random symbol
        sym_in = rand() % M;

        // modulate
        modem_modulate(mod, sym_in, &x);

        // channel
        //r = nco_crcf_cexpf(nco_tx);
        nco_crcf_mix_up(nco_tx, x, &r);

        // add complex white noise
        crandnf(&noise);
        r += noise * noise_power;

        // 
        //v = nco_crcf_cexpf(nco_rx);
        nco_crcf_mix_down(nco_rx, r, &v);

        // demodulate
        modem_demodulate(demod, v, &sym_out);
        num_errors += count_bit_errors(sym_in, sym_out);

        // error estimation
        //phase_error = cargf(r*conjf(v));
        phase_error = modem_get_demodulator_phase_error(demod);

        // perfect error estimation
        //phase_error = nco_tx->theta - nco_rx->theta;

        // print every line in a format that octave can read
        fprintf(fid, "phi(%u) = %10.6E;\n", i+1, phase_error);
        fprintf(fid, "r(%u) = %10.6E + j*%10.6E;\n",
                i+1, crealf(v), cimagf(v));

        if ((i+1)%d == 0 || i==n-1) {
            printf("  %4u: e_hat : %6.3f, phase error : %6.3f, freq error : %6.3f\n",
                    i+1,                                // iteration
                    phase_error,                        // estimated phase error
                    nco_crcf_get_phase(nco_tx) - nco_crcf_get_phase(nco_rx),// true phase error
                    nco_crcf_get_frequency(nco_tx) - nco_crcf_get_frequency(nco_rx)// true frequency error
                  );
        }

        // update tx nco object
        nco_crcf_step(nco_tx);

        // update pll
        nco_crcf_pll_step(nco_rx, phase_error);

        // update rx nco object
        nco_crcf_step(nco_rx);
    }

    fprintf(fid, "figure;\n");
    fprintf(fid, "plot(1:length(phi),phi,'LineWidth',2,'Color',[0 0.25 0.5]);\n");
    fprintf(fid, "xlabel('Symbol Index');\n");
    fprintf(fid, "ylabel('Phase Error [radians]');\n");
    fprintf(fid, "grid on;\n");

    fprintf(fid, "t0 = round(0.25*length(r));\n");
    fprintf(fid, "figure;\n");
    fprintf(fid, "plot(r(1:t0),'x','Color',[0.6 0.6 0.6],r(t0:end),'x','Color',[0 0.25 0.5]);\n");
    fprintf(fid, "grid on;\n");
    fprintf(fid, "axis([-1.5 1.5 -1.5 1.5]);\n");
    fprintf(fid, "axis('square');\n");
    fprintf(fid, "xlabel('In-Phase');\n");
    fprintf(fid, "ylabel('Quadrature');\n");
    fprintf(fid, "legend(['first 25%%'],['last 75%%'],1);\n");
    fclose(fid);

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

    nco_crcf_destroy(nco_tx);
    nco_crcf_destroy(nco_rx);

    modem_destroy(mod);
    modem_destroy(demod);

    printf("bit errors: %u / %u\n", num_errors, bps*n);
    printf("done.\n");
    return 0;
}
示例#4
0
int main(int argc, char*argv[])
{
    srand(time(NULL));

    // options
    unsigned int M = 64;                // number of subcarriers
    unsigned int cp_len = 16;           // cyclic prefix length
    unsigned int taper_len = 4;         // taper length
    unsigned int payload_len = 120;     // length of payload (bytes)
    modulation_scheme ms = LIQUID_MODEM_QPSK;
    fec_scheme fec0  = LIQUID_FEC_NONE;
    fec_scheme fec1  = LIQUID_FEC_HAMMING128;
    crc_scheme check = LIQUID_CRC_32;
    float noise_floor = -30.0f;         // noise floor [dB]
    float SNRdB = 20.0f;                // signal-to-noise ratio [dB]
    float dphi = 0.02f;                 // carrier frequency offset
    int debug_enabled =  0;             // enable debugging?

    // get options
    int dopt;
    while((dopt = getopt(argc,argv,"uhds:F:M:C:n:m:v:c:k:")) != EOF){
        switch (dopt) {
        case 'u':
        case 'h': usage();                      return 0;
        case 'd': debug_enabled = 1;            break;
        case 's': SNRdB         = atof(optarg); break;
        case 'F': dphi          = atof(optarg); break;
        case 'M': M             = atoi(optarg); break;
        case 'C': cp_len        = atoi(optarg); break;
        case 'n': payload_len   = atol(optarg); break;
        case 'm':
            ms = liquid_getopt_str2mod(optarg);
            if (ms == LIQUID_MODEM_UNKNOWN) {
                fprintf(stderr,"error: %s, unknown/unsupported mod. scheme: %s\n", argv[0], optarg);
                exit(-1);
            }
            break;
        case 'v':
            // data integrity check
            check = liquid_getopt_str2crc(optarg);
            if (check == LIQUID_CRC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported CRC scheme \"%s\"\n\n",optarg);
                exit(1);
            }
            break;
        case 'c':
            // inner FEC scheme
            fec0 = liquid_getopt_str2fec(optarg);
            if (fec0 == LIQUID_FEC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported inner FEC scheme \"%s\"\n\n",optarg);
                exit(1);
            }
            break;
        case 'k':
            // outer FEC scheme
            fec1 = liquid_getopt_str2fec(optarg);
            if (fec1 == LIQUID_FEC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported outer FEC scheme \"%s\"\n\n",optarg);
                exit(1);
            }
            break;
        default:
            exit(-1);
        }
    }

    unsigned int i;

    // TODO : validate options

    // derived values
    unsigned int frame_len = M + cp_len;
    float complex buffer[frame_len]; // time-domain buffer
    float nstd = powf(10.0f, noise_floor/20.0f);
    float gamma = powf(10.0f, (SNRdB + noise_floor)/20.0f);

    // allocate memory for header, payload
    unsigned char header[8];
    unsigned char payload[payload_len];

    // initialize subcarrier allocation
    unsigned char p[M];
    ofdmframe_init_default_sctype(M, p);

    // create frame generator
    ofdmflexframegenprops_s fgprops;
    ofdmflexframegenprops_init_default(&fgprops);
    fgprops.check           = check;
    fgprops.fec0            = fec0;
    fgprops.fec1            = fec1;
    fgprops.mod_scheme      = ms;
    ofdmflexframegen fg = ofdmflexframegen_create(M, cp_len, taper_len, p, &fgprops);

    // create frame synchronizer
    ofdmflexframesync fs = ofdmflexframesync_create(M, cp_len, taper_len, p, callback, (void*)payload);
    if (debug_enabled)
        ofdmflexframesync_debug_enable(fs);

    // initialize header/payload and assemble frame
    for (i=0; i<8; i++)
        header[i] = i & 0xff;
    for (i=0; i<payload_len; i++)
        payload[i] = rand() & 0xff;
    ofdmflexframegen_assemble(fg, header, payload, payload_len);
    ofdmflexframegen_print(fg);
    ofdmflexframesync_print(fs);

    // initialize frame synchronizer with noise
    for (i=0; i<1000; i++) {
        float complex noise = nstd*( randnf() + _Complex_I*randnf())*M_SQRT1_2;
        ofdmflexframesync_execute(fs, &noise, 1);
    }

    // generate frame, push through channel
    int last_symbol=0;
    nco_crcf nco = nco_crcf_create(LIQUID_VCO);
    nco_crcf_set_frequency(nco, dphi);
    while (!last_symbol) {
        // generate symbol
        last_symbol = ofdmflexframegen_writesymbol(fg, buffer);

        // apply channel
        for (i=0; i<frame_len; i++) {
            float complex noise = nstd*( randnf() + _Complex_I*randnf())*M_SQRT1_2;
            buffer[i] *= gamma;
            buffer[i] += noise;
            
            nco_crcf_mix_up(nco, buffer[i], &buffer[i]);
            nco_crcf_step(nco);
        }

        // receive symbol
        ofdmflexframesync_execute(fs, buffer, frame_len);
    }
    nco_crcf_destroy(nco);

    // export debugging file
    if (debug_enabled)
        ofdmflexframesync_debug_print(fs, "ofdmflexframesync_debug.m");

    // destroy objects
    ofdmflexframegen_destroy(fg);
    ofdmflexframesync_destroy(fs);

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