void LiquidOfdmModComponent::initialize()
{
    // print capabilities of liquid
    if (debug_x) {
        liquid_print_modulation_schemes();
        liquid_print_fec_schemes();
        liquid_print_crc_schemes();
    }

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

    // create frame generator properties object and initialize to default
    ofdmflexframegenprops_s fgProps;
    ofdmflexframegenprops_init_default(&fgProps);
    modulation_scheme ms = liquid_getopt_str2mod(modulationScheme_x.c_str());
    fec_scheme fec0 = liquid_getopt_str2fec(fecZero_x.c_str());
    fec_scheme fec1 = liquid_getopt_str2fec(fecOne_x.c_str());
    crc_scheme check = liquid_getopt_str2crc(crcScheme_x.c_str());

    fgProps.mod_scheme = ms;
    fgProps.fec0 = fec0;
    fgProps.fec1 = fec1;
    fgProps.check = check;

    gain_factor_  = powf(10.0f, gain_x/20.0f);

    // create frame generator object
    try {
        frameGenerator_ = ofdmflexframegen_create(noSubcarriers_x, cyclicPrefixLength_x, taperLength_x, p, &fgProps);
        ofdmflexframegen_print(frameGenerator_);
    }
    catch(...)
    {
        LOG(LERROR) << "Unexpected exception caught during frame generator generation";
    }
}
void LiquidOfdmModComponent::parameterHasChanged(std::string name)
{
    ofdmflexframegenprops_s fgProps;
    ofdmflexframegen_getprops(frameGenerator_, &fgProps);
    if (name == "modulation") {
        modulation_scheme ms = liquid_getopt_str2mod(modulationScheme_x.c_str());
        fgProps.mod_scheme = ms;
    }
    if (name == "fec0") {
        fec_scheme fec0 = liquid_getopt_str2fec(fecZero_x.c_str());
        fgProps.fec0 = fec0;
    }
    if (name == "fec1") {
        fec_scheme fec1 = liquid_getopt_str2fec(fecOne_x.c_str());
        fgProps.fec1 = fec1;
    }
    if (name == "crc") {
        crc_scheme check = liquid_getopt_str2crc(crcScheme_x.c_str());
        fgProps.check = check;
    }
    ofdmflexframegen_setprops(frameGenerator_, &fgProps);

    if (name == "gain") {
        gain_factor_  = powf(10.0f, gain_x/20.0f);
    }

    if (name == "subcarriers" ||
        name == "prefixlength" ||
        name == "taperlength")
    {
      //Need to destroy and recreate the frame generator
      if (frameGenerator_)
        ofdmflexframegen_destroy(frameGenerator_);
      initialize();
    }
}
Example #3
0
int main(int argc, char*argv[])
{
    srand( time(NULL) );

    // options
    int verbose = 1;
    int which_ber_per  = ESTIMATE_SNR_BER;
    int which_snr_ebn0 = ESTIMATE_SNR;
    float error_rate = 1e-3f;
    unsigned int frame_len = 1024;
    unsigned long int max_trials = 0;

    modulation_scheme ms = LIQUID_MODEM_QPSK;
    fec_scheme fec0 = LIQUID_FEC_NONE;  // inner code
    fec_scheme fec1 = LIQUID_FEC_NONE;  // outer code
    int soft_decoding = 0;

    int dopt;
    while ((dopt = getopt(argc,argv,"uhvqBPseSHE:n:x:c:m:")) != EOF) {
        switch (dopt) {
        case 'u':
        case 'h': usage();                          return 0;
        case 'v': verbose = 1;                      break;
        case 'q': verbose = 0;                      break;
        case 'B': which_ber_per = ESTIMATE_SNR_BER; break;
        case 'P': which_ber_per = ESTIMATE_SNR_PER; break;
        case 's': which_snr_ebn0 = ESTIMATE_SNR;    break;
        case 'e': which_snr_ebn0 = ESTIMATE_EBN0;   break;
        case 'S': soft_decoding = 1;                break;
        case 'H': soft_decoding = 0;                break;
        case 'E': error_rate = atof(optarg);        break;
        case 'n': frame_len = atoi(optarg);         break;
        case 'x': max_trials = atoi(optarg);        break;
        case 'c':
            // 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 'm':
            ms = liquid_getopt_str2mod(optarg);
            if (ms == LIQUID_MODEM_UNKNOWN) {
                fprintf(stderr,"error: modem_example, unknown/unsupported modulation scheme \"%s\"\n", optarg);
                return 1;
            }
            break;
        default:
            exit(1);
        }
    }

    // validate input
    if (error_rate <= 0.0f) {
        fprintf(stderr,"error: error rate must be greater than 0\n");
        exit(1);
    } else if (frame_len == 0 || frame_len > 10000) {
        fprintf(stderr,"error: frame length must be in [1, 10,000]\n");
        exit(1);
    } else if (which_ber_per == ESTIMATE_SNR_BER && error_rate >= 0.5) {
        fprintf(stderr,"error: error rate must be less than 0.5 when simulating BER\n");
        exit(1);
    } else if (error_rate >= 1.0f) {
        fprintf(stderr,"error: error rate must be less than 1\n");
        exit(1);
    }

    if (max_trials == 0) {
        // unspecified: use defaults
        if (which_ber_per == ESTIMATE_SNR_BER)
            max_trials = 800000;
        else
            max_trials = 200;
    }

    simulate_per_opts opts;
    opts.ms     = ms;
    opts.fec0   = fec0;
    opts.fec1   = fec1;
    opts.dec_msg_len = frame_len;
    opts.soft_decoding = soft_decoding;
    
    unsigned int bps = modulation_types[ms].bps;

    // minimum number of errors to simulate
    opts.min_packet_errors  = which_ber_per==ESTIMATE_SNR_PER ? 10      : 0;
    opts.min_bit_errors     = which_ber_per==ESTIMATE_SNR_BER ? 50      : 0;

    // minimum number of trials to simulate
    opts.min_packet_trials  = which_ber_per==ESTIMATE_SNR_PER ? 500     : 0;
    opts.min_bit_trials     = which_ber_per==ESTIMATE_SNR_BER ? 5000    : 0;

    // maximum number of trials to simulate (before bailing and
    // deeming simulation unsuccessful)
    opts.max_packet_trials  = which_ber_per==ESTIMATE_SNR_PER ? max_trials : -1; 
    opts.max_bit_trials     = which_ber_per==ESTIMATE_SNR_BER ? max_trials : -1; 

    // estimate SNR for a specific PER
    printf("%u-%s // %s // %s (%s: %e)\n", 1<<bps,
                                           modulation_types[opts.ms].name,
                                           fec_scheme_str[opts.fec0][0],
                                           fec_scheme_str[opts.fec1][0],
                                           which_ber_per == ESTIMATE_SNR_BER ? "BER" : "PER",
                                           error_rate);

    // run estimation
    float x_hat = estimate_snr(opts, which_ber_per, which_snr_ebn0, error_rate);

    // compute rate [b/s/Hz]
    float rate = bps * fec_get_rate(opts.fec0) * fec_get_rate(opts.fec1);

    // set estimated values
    float SNRdB_hat;
    float EbN0dB_hat;
    if (which_snr_ebn0==ESTIMATE_SNR) {
        SNRdB_hat = x_hat;
        EbN0dB_hat = SNRdB_hat - 10*log10f(rate);
    } else {
        SNRdB_hat = x_hat + 10*log10f(rate);
        EbN0dB_hat = x_hat;
    }
    if (verbose) {
        printf("++ SNR (est) : %8.4fdB (Eb/N0 = %8.4fdB) for %s: %12.4e\n",
                SNRdB_hat,
                EbN0dB_hat,
                which_ber_per == ESTIMATE_SNR_BER ? "BER" : "PER",
                error_rate);
    }


    printf("done.\n");
    return 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;  // modulation scheme
    fec_scheme        fec0        = LIQUID_FEC_NONE;    // inner code
    fec_scheme        fec1        = LIQUID_FEC_HAMMING128; // outer code
    crc_scheme        check       = LIQUID_CRC_32;      // validity check
    float             noise_floor = -80.0f;             // noise floor [dB]
    float             SNRdB       = 20.0f;              // signal-to-noise ratio [dB]
    float             dphi        = 0.02f;              // carrier frequency offset
    int               debug       =  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       = 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); break;
        case 'v': check       = liquid_getopt_str2crc(optarg); break;
        case 'c': fec0        = liquid_getopt_str2fec(optarg); break;
        case 'k': fec1        = liquid_getopt_str2fec(optarg); break;
        default:
            exit(-1);
        }
    }

    unsigned int i;

    // TODO : validate options

    // derived values
    unsigned int  buf_len = 256;
    float complex buf[buf_len]; // time-domain buffer

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

    // 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, NULL, &fgprops);

    // create frame synchronizer
    ofdmflexframesync fs = ofdmflexframesync_create(M, cp_len, taper_len, NULL, callback, (void*)payload);
    if (debug)
        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);

    // create channel and add impairments
    channel_cccf channel = channel_cccf_create();
    channel_cccf_add_awgn(channel, noise_floor, SNRdB);
    channel_cccf_add_carrier_offset(channel, dphi, 0.0f);

    // generate frame, push through channel
    int last_symbol=0;
    while (!last_symbol) {
        // generate symbol
        last_symbol = ofdmflexframegen_write(fg, buf, buf_len);

        // apply channel to buffer (in place)
        channel_cccf_execute_block(channel, buf, buf_len, buf);

        // push samples through synchronizer
        ofdmflexframesync_execute(fs, buf, buf_len);
    }

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

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

    printf("done.\n");
    return 0;
}
int main(int argc, char*argv[]) {
    srand( time(NULL) );

    // options
    simulate_per_opts opts;
    opts.ms = LIQUID_MODEM_BPSK;
    opts.bps = 1;
    opts.fec0 = LIQUID_FEC_NONE;
    opts.fec1 = LIQUID_FEC_NONE;
    opts.dec_msg_len = 1024;
    opts.soft_decoding = 1;

    opts.min_packet_errors  = 5;
    opts.min_bit_errors     = 10;
    opts.min_packet_trials  = 50;
    opts.min_bit_trials     = 10000;

    opts.max_packet_trials  = 1000;
    opts.max_bit_trials     = 1000000;

    // read command-line options
    int dopt;
    while((dopt = getopt(argc,argv,"uhn:p:m:c:k:SH")) != EOF){
        switch (dopt) {
        case 'h':
        case 'u': usage();                          return 0;
        case 'n': opts.dec_msg_len = atoi(optarg);  break;
        case 'p': opts.bps = atoi(optarg);          break;
        case 'm':
            opts.ms = liquid_getopt_str2mod(optarg);
            if (opts.ms == LIQUID_MODEM_UNKNOWN) {
                fprintf(stderr,"error: modem_example, unknown/unsupported modulation scheme \"%s\"\n", optarg);
                exit(1);
            }
            break;
        case 'c':
            // inner FEC scheme
            opts.fec0 = liquid_getopt_str2fec(optarg);
            if (opts.fec0 == LIQUID_FEC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported modulation scheme \"%s\"\n\n",optarg);
                exit(-1);
            }
            break;
        case 'k':
            // outer FEC scheme
            opts.fec1 = liquid_getopt_str2fec(optarg);
            if (opts.fec1 == LIQUID_FEC_UNKNOWN) {
                fprintf(stderr,"error: unknown/unsupported modulation scheme \"%s\"\n\n",optarg);
                exit(-1);
            }
            break;
        case 'S': opts.soft_decoding = 1;   break;
        case 'H': opts.soft_decoding = 0;   break;
        default:
            exit(1);
        }
    }


    // SNR range, steps
    float SNRdB_min = 0.0f;
    float SNRdB_max = 20.0f;
    unsigned int num_steps = 21;

    // derived values
    float SNRdB_step = (SNRdB_max - SNRdB_min)/(float)(num_steps-1);

    //
    float SNRdB;

    // generate results structure
    simulate_per_results results;

    // array for BER
    float BER[num_steps];

    unsigned int i;
    for (i=0; i<num_steps; i++) {
        SNRdB = SNRdB_min + i*SNRdB_step;

        simulate_per(opts, SNRdB, &results);

        //printf("  %12.8f : %12.4e\n", SNRdB, PER);
        printf(" %c SNR: %6.2f, bits: %8lu / %8lu (%12.4e), packets: %6lu / %6lu (%6.2f%%)\n",
                results.success ? '*' : ' ',
                SNRdB,
                results.num_bit_errors,     results.num_bit_trials,     results.BER,
                results.num_packet_errors,  results.num_packet_trials,  results.PER*100.0f);

        // save BER in array
        BER[i] = results.BER;
    }

    // 
    // export data
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    if (!fid) {
        fprintf(stderr,"error: %s, could not open '%s' for writing\n", argv[0], OUTPUT_FILENAME);
        exit(1);
    }
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n");
    for (i=0; i<num_steps; i++) {
        fprintf(fid,"SNRdB(%3u) = %12.8f;\n", i+1, SNRdB_min + i*SNRdB_step);
        fprintf(fid,"BER(%3u)   = %12.4e;\n", i+1, BER[i]);
    }
    fprintf(fid,"\n\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"semilogy(SNRdB, 0.5*erfc(sqrt(10.^[SNRdB/10]))+1e-12,'-x',\n");
    fprintf(fid,"         SNRdB, BER + 1e-12,  '-x');\n");
    fprintf(fid,"axis([%f %f 1e-6 1]);\n", SNRdB_min, SNRdB_max);
    fprintf(fid,"xlabel('SNR [dB]');\n");
    fprintf(fid,"ylabel('Bit Error Rate');\n");
    fprintf(fid,"legend('uncoded BPSK','modem: %s (M=%u) // fec: %s',1);\n",
            modulation_types[opts.ms].name, 1<<opts.bps, fec_scheme_str[opts.fec0][0]);
    fprintf(fid,"grid on;\n");

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

    printf("done.\n");
    return 0;
}
Example #6
0
int main(int argc, char *argv[])
{
    //srand( time(NULL) );

    // options
    modulation_scheme ms     =  LIQUID_MODEM_QPSK; // mod. scheme
    crc_scheme check         =  LIQUID_CRC_32;     // data validity check
    fec_scheme fec0          =  LIQUID_FEC_NONE;   // fec (inner)
    fec_scheme fec1          =  LIQUID_FEC_NONE;   // fec (outer)
    unsigned int payload_len =  120;               // payload length
    int debug_enabled        =  0;                 // enable debugging?
    float noise_floor        = -60.0f;             // noise floor
    float SNRdB              =  20.0f;             // signal-to-noise ratio
    float dphi               =  0.01f;             // carrier frequency offset

    // get options
    int dopt;
    while((dopt = getopt(argc,argv,"uhs:F:n:m:v:c:k:d")) != EOF){
        switch (dopt) {
        case 'u':
        case 'h': usage();                                       return 0;
        case 's': SNRdB         = atof(optarg);                  break;
        case 'F': dphi          = atof(optarg);                  break;
        case 'n': payload_len   = atol(optarg);                  break;
        case 'm': ms            = liquid_getopt_str2mod(optarg); break;
        case 'v': check         = liquid_getopt_str2crc(optarg); break;
        case 'c': fec0          = liquid_getopt_str2fec(optarg); break;
        case 'k': fec1          = liquid_getopt_str2fec(optarg); break;
        case 'd': debug_enabled = 1;                             break;
        default:
            exit(-1);
        }
    }

    // derived values
    unsigned int i;
    float nstd  = powf(10.0f, noise_floor/20.0f);         // noise std. dev.
    float gamma = powf(10.0f, (SNRdB+noise_floor)/20.0f); // channel gain

    // create flexframegen object
    flexframegenprops_s fgprops;
    flexframegenprops_init_default(&fgprops);
    fgprops.mod_scheme  = ms;
    fgprops.check       = check;
    fgprops.fec0        = fec0;
    fgprops.fec1        = fec1;
    flexframegen fg = flexframegen_create(&fgprops);

    // frame data (header and payload)
    unsigned char header[14];
    unsigned char payload[payload_len];

    // create flexframesync object
    flexframesync fs = flexframesync_create(callback,NULL);
    if (debug_enabled)
        flexframesync_debug_enable(fs);

    // initialize header, payload
    for (i=0; i<14; i++)
        header[i] = i;
    for (i=0; i<payload_len; i++)
        payload[i] = rand() & 0xff;

    // assemble the frame
    flexframegen_assemble(fg, header, payload, payload_len);
    flexframegen_print(fg);

    // generate the frame in blocks
    unsigned int  buf_len = 256;
    float complex x[buf_len];
    float complex y[buf_len];

    int frame_complete = 0;
    float phi = 0.0f;
    while (!frame_complete) {
        // write samples to buffer
        frame_complete = flexframegen_write_samples(fg, x, buf_len);

        // add noise and push through synchronizer
        for (i=0; i<buf_len; i++) {
            // apply channel gain and carrier offset to input
            y[i] = gamma * x[i] * cexpf(_Complex_I*phi);
            phi += dphi;

            // add noise
            y[i] += nstd*( randnf() + _Complex_I*randnf())*M_SQRT1_2;
        }

        // run through frame synchronizer
        flexframesync_execute(fs, y, buf_len);
    }

    // export debugging file
    if (debug_enabled)
        flexframesync_debug_print(fs, "flexframesync_debug.m");

    flexframesync_print(fs);
    // destroy allocated objects
    flexframegen_destroy(fg);
    flexframesync_destroy(fs);

    printf("done.\n");
    return 0;
}
Example #7
0
int main(int argc, char*argv[]) {
    srand(time(NULL));

    // options
    unsigned int n=8;                       // original data message length
    crc_scheme check = LIQUID_CRC_32;       // data integrity check
    fec_scheme fec0 = LIQUID_FEC_HAMMING74; // inner code
    fec_scheme fec1 = LIQUID_FEC_NONE;      // outer code
    float bit_error_rate = 0.0f;            // bit error rate

    // read command-line options
    int dopt;
    while((dopt = getopt(argc,argv,"uhn:e:v:c:k:")) != EOF){
        switch (dopt) {
        case 'h':
        case 'u': usage(); return 0;
        case 'n': n = atoi(optarg);     break;
        case 'e': bit_error_rate = atof(optarg);     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);
        }
    }

    // validate input
    if (n == 0) {
        fprintf(stderr,"error: %s, packet length must be greater than zero\n", argv[0]);
        exit(1);
    } else if (bit_error_rate < 0.0f || bit_error_rate > 1.0f) {
        fprintf(stderr,"error: %s, channel bit error rate must be in [0,1]\n", argv[0]);
        exit(1);
    }

    // create packet generator
    bpacketgen pg = bpacketgen_create(0, n, check, fec0, fec1);
    bpacketgen_print(pg);

    unsigned int i;

    // compute packet length
    unsigned int k = bpacketgen_get_packet_len(pg);

    // initialize arrays
    unsigned char msg_org[n];   // original message
    unsigned char msg_enc[k];   // encoded message
    unsigned char msg_rec[k+1]; // recieved message
    unsigned char msg_dec[n];   // decoded message

    // create packet synchronizer
    bpacketsync ps = bpacketsync_create(0, callback, (void*)msg_dec);

    // initialize original data message
    for (i=0; i<n; i++)
        msg_org[i] = rand() % 256;

    // 
    // encode packet
    //
    bpacketgen_encode(pg,msg_org,msg_enc);

    // 
    // channel
    //
    // add delay
    msg_rec[0] = rand() & 0xff; // initialize first byte as random
    memmove(&msg_rec[1], msg_enc, k*sizeof(unsigned char));
    liquid_lbshift(msg_rec, (k+1)*sizeof(unsigned char), rand()%8); // random shift
    // add random errors
    for (i=0; i<k+1; i++) {
        unsigned int j;
        for (j=0; j<8; j++) {
            if (randf() < bit_error_rate)
                msg_rec[i] ^= 1 << (8-j-1);
        }
    }

    // 
    // run packet synchronizer
    //

    // push random bits through synchronizer
    for (i=0; i<100; i++)
        bpacketsync_execute_byte(ps, rand() & 0xff);

    // push packet through synchronizer
    for (i=0; i<k+1; i++)
        bpacketsync_execute_byte(ps, msg_rec[i]);

    // 
    // count errors
    //
    unsigned int num_bit_errors = 0;
    for (i=0; i<n; i++)
        num_bit_errors += count_bit_errors(msg_org[i], msg_dec[i]);
    printf("number of bit errors received:    %4u / %4u\n", num_bit_errors, n*8);

    // clean up allocated objects
    bpacketgen_destroy(pg);
    bpacketsync_destroy(ps);

    return 0;
}
Example #8
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;
}
int main(int argc, char*argv[]) {
    // options
    unsigned int n=8;                       // original data message length
    crc_scheme check = LIQUID_CRC_32;       // data integrity check
    fec_scheme fec0 = LIQUID_FEC_HAMMING74; // inner code
    fec_scheme fec1 = LIQUID_FEC_NONE;      // outer code

    // read command-line options
    int dopt;
    while((dopt = getopt(argc,argv,"uhn:v:c:k:")) != EOF){
        switch (dopt) {
        case 'h':
        case 'u': usage(); return 0;
        case 'n':
            n = atoi(optarg);
            if (n < 1) {
                printf("error: packet length must be positive\n");
                usage();
                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;
    unsigned int k = packetizer_compute_enc_msg_len(n,check,fec0,fec1);
    packetizer p = packetizer_create(n,check,fec0,fec1);
    packetizer_print(p);

    // initialize arrays
    unsigned char msg_org[n];   // original message
    unsigned char msg_enc[k];   // encoded message
    unsigned char msg_rec[8*k]; // recieved message (soft bits)
    unsigned char msg_dec[n];   // decoded message
    int crc_pass;

    // initialize original data message
    for (i=0; i<n; i++)
        msg_org[i] = rand() % 256;

    // encode packet
    packetizer_encode(p,msg_org,msg_enc);

    // convert to soft bits and add 'noise'
    for (i=0; i<k; i++) {
        msg_rec[8*i+0] = (msg_enc[i] & 0x80) ? 255 : 0;
        msg_rec[8*i+1] = (msg_enc[i] & 0x40) ? 255 : 0;
        msg_rec[8*i+2] = (msg_enc[i] & 0x20) ? 255 : 0;
        msg_rec[8*i+3] = (msg_enc[i] & 0x10) ? 255 : 0;
        msg_rec[8*i+4] = (msg_enc[i] & 0x08) ? 255 : 0;
        msg_rec[8*i+5] = (msg_enc[i] & 0x04) ? 255 : 0;
        msg_rec[8*i+6] = (msg_enc[i] & 0x02) ? 255 : 0;
        msg_rec[8*i+7] = (msg_enc[i] & 0x01) ? 255 : 0;
    }

    // flip first bit (ensure error)
    msg_rec[0] = 255 - msg_rec[0];

    // add noise (but not so much that it would cause a bit error)
    for (i=0; i<8*k; i++) {
        int soft_bit = msg_rec[i] + (int)(20*randnf());
        if (soft_bit > 255) soft_bit = 255;
        if (soft_bit <   0) soft_bit = 0;
        msg_rec[i] = soft_bit;
    }

    // decode packet
    crc_pass =
    packetizer_decode_soft(p,msg_rec,msg_dec);

    // clean up allocated objects
    packetizer_destroy(p);

    // print results
    printf("original message:  [%3u] ",n);
    for (i=0; i<n; i++)
        printf(" %.2X", (unsigned int) (msg_org[i]));
    printf("\n");

    printf("encoded message:   [%3u] ",k);
    for (i=0; i<k; i++)
        printf(" %.2X", (unsigned int) (msg_enc[i]));
    printf("\n");

#if 0
    printf("received message:  [%3u] ",k);
    for (i=0; i<k; i++)
        printf("%c%.2X", msg_rec[i]==msg_enc[i] ? ' ' : '*', (unsigned int) (msg_rec[i]));
    printf("\n");
#endif

    //if (verbose) {
    if (1) {
        // print expanded result (print each soft bit value)
        for (i=0; i<k; i++) {
            unsigned char msg_cor_hard = 0x00;
            printf("%5u: ", i);
            unsigned int j;
            for (j=0; j<8; j++) {
                msg_cor_hard |= (msg_rec[8*i+j] > 127) ? 1<<(8-j-1) : 0;
                unsigned int bit_enc = (msg_enc[i] >> (8-j-1)) & 0x01;
                unsigned int bit_rec = (msg_rec[8*i+j] > 127) ? 1 : 0;
                //printf("%1u %3u (%1u) %c", bit_enc, msg_rec[i], bit_rec, bit_enc != bit_rec ? '*' : ' ');
                printf("%4u%c", msg_rec[8*i+j], bit_enc != bit_rec ? '*' : ' ');
            }
            printf("  :  %c%.2X\n", msg_cor_hard==msg_enc[i] ? ' ' : '*', (unsigned int) (msg_cor_hard));
        }
    } // verbose


    printf("decoded message:   [%3u] ",n);
    for (i=0; i<n; i++)
        printf("%c%.2X", msg_dec[i] == msg_org[i] ? ' ' : '*', (unsigned int) (msg_dec[i]));
    printf("\n");
    printf("\n");

    // count bit errors
    unsigned int num_sym_errors=0;
    unsigned int num_bit_errors=0;
    for (i=0; i<n; i++) {
        num_sym_errors += (msg_org[i] == msg_dec[i]) ? 0 : 1;

        num_bit_errors += count_bit_errors(msg_org[i], msg_dec[i]);
    }

    //printf("number of symbol errors detected: %d\n", num_errors_detected);
    printf("number of symbol errors received: %4u / %4u\n", num_sym_errors, n);
    printf("number of bit errors received:    %4u / %4u\n", num_bit_errors, n*8);

    if (crc_pass)
        printf("(crc passed)\n");
    else
        printf("(crc failed)\n");

    return 0;
}
Example #10
0
int main(int argc, char *argv[]) {
    srand( time(NULL) );

    // define parameters
    float SNRdB_start       = -5.0f;
    float SNRdB_step        = 1.0f;
    float SNRdB_max         = 10.0f;
    unsigned int num_frames = 1000;
    //float noise_floor       = -30.0f;
    const char * filename   = "ofdmflexframe_fer_results.dat";
    modulation_scheme ms    = LIQUID_MODEM_QPSK;
    unsigned int M          = 64;
    unsigned int cp_len     = 16;
    unsigned int payload_len= 256;
    crc_scheme check        = LIQUID_CRC_32;
    fec_scheme fec0         = LIQUID_FEC_HAMMING128;
    fec_scheme fec1         = LIQUID_FEC_NONE;
    int verbose             = 1;

    // get command-line options
    int dopt;
    while((dopt = getopt(argc,argv,"uho:s:d:x:n:f:M:C:m:c:k:")) != EOF){
        switch (dopt) {
        case 'h':
        case 'u': usage(); return 0;
        case 'o': filename = optarg;            break;
        case 's': SNRdB_start = atof(optarg);   break;
        case 'd': SNRdB_step = atof(optarg);    break;
        case 'x': SNRdB_max = atof(optarg);     break;
        case 'n': num_frames = atol(optarg);    break;
        case 'f': payload_len = atol(optarg);   break;
        case 'M': M = atoi(optarg);             break;
        case 'C': cp_len = atoi(optarg);        break;
        case 'm':
            ms = liquid_getopt_str2mod(optarg);
            if (ms == LIQUID_MODEM_UNKNOWN) {
                printf("error: unknown/unsupported mod. scheme: %s\n", optarg);
                exit(1);
            }
            break;
        case 'c':
            fec0 = liquid_getopt_str2fec(optarg);
            if (fec0 == LIQUID_FEC_UNKNOWN) {
                printf("error: unknown/unsupported fec scheme \"%s\"\n", optarg);
                exit(1);
            }
            break;
        case 'k':
            fec1 = liquid_getopt_str2fec(optarg);
            if (fec1 == LIQUID_FEC_UNKNOWN) {
                printf("error: unknown/unsupported fec scheme \"%s\"\n", optarg);
                exit(1);
            }
            break;
        default:
            fprintf(stderr,"error: %s, unknown option\n", argv[0]);
            exit(1);
        }
    }

    // validate options
    if (SNRdB_step <= 0.0f) {
        printf("error: SNRdB_step must be greater than zero\n");
        exit(-1);
    } else if (SNRdB_max < SNRdB_start) {
        printf("error: SNRdB_max must be greater than SNRdB_start\n");
        exit(-1);
    }

    // set up framing simulation options
    ofdmflexframe_fer_opts opts;
    opts.M          = M;
    opts.cp_len     = cp_len;
    opts.p          = NULL;
    opts.ms         = ms;
    opts.check      = check;
    opts.fec0       = fec0;
    opts.fec1       = fec1;
    opts.payload_len= payload_len;
    opts.num_frames = num_frames;
    opts.verbose    = verbose;

    // create results objects
    fer_results results;

    // bookkeeping variables
    unsigned int i;
    float SNRdB = SNRdB_start;

    // open output file
    FILE * fid = fopen(filename,"w");
    if (!fid) {
        fprintf(stderr,"error: could not open '%s' for writing\n", filename);
        exit(1);
    }
    fprintf(fid,"# %s : auto-generated file\n", filename);
    fprintf(fid,"# invoked as: ");
    for (i=0; i<argc; i++) fprintf(fid,"%s ", argv[i]);
    fprintf(fid,"\n");
    fprintf(fid,"#\n");
    fprintf(fid,"#  M (subcarriers)     :   %u\n", opts.M);
    fprintf(fid,"#  cyclic prefix       :   %u\n", opts.cp_len);
    fprintf(fid,"#  allocation          :   \n"); // ofdmframe_print_sctype(opts.p, opts.M);
    fprintf(fid,"#  modulation scheme   :   %s\n", modulation_types[opts.ms].fullname);
    fprintf(fid,"#  modulation depth    :   %u bits/symbol\n", modulation_types[opts.ms].bps);
    fprintf(fid,"#  check               :   %s\n", crc_scheme_str[opts.check][1]);
    fprintf(fid,"#  fec (inner)         :   %s\n", fec_scheme_str[opts.fec0][1]);
    fprintf(fid,"#  fec (outer)         :   %s\n", fec_scheme_str[opts.fec1][1]);
    fprintf(fid,"#  payload length      :   %u bytes\n", opts.payload_len);
    fprintf(fid,"#  frame trials        :   %u\n", opts.num_frames);
    fprintf(fid,"#\n");
    fprintf(fid,"# %8s %12s %12s %12s %12s %12s %12s %12s\n",
            "SNR [dB]",
            "FER (frame)",
            "HER (header)",
            "PER (packet)",
            "frames",
            "headers",
            "packets",
            "num trials");
    fclose(fid);

    // start running batch trials
    while (SNRdB <= SNRdB_max) {

        // run trials
        ofdmflexframe_fer(opts, SNRdB, &results);

        // append results to file
        fid = fopen(filename,"a");
        fprintf(fid,"  %8.2f %12.10f %12.10f %12.10f %12u %12u %12u %12u\n",
                SNRdB,
                results.FER,
                results.HER,
                results.PER,
                results.num_missed_frames,
                results.num_header_errors,
                results.num_packet_errors,
                results.num_frames);
        fclose(fid);

        SNRdB += SNRdB_step;
    }

    printf("results written to '%s'\n", filename);

    return 0;
}