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(); } }
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; }
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; }
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; }
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; }
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; }