std::complex < double > MAskFunction::calc(const double &inpt) { (void)inpt; // Create result object, the result of mod will be placed in this. liquid_float_complex res{0.0f, 0.0f}; // Modulate a random symbol. modem_modulate(_mod, modem_gen_rand_sym(_mod), &res); return std::complex<double>((double)res.real, (double)res.imag); }
// write header symbol void ofdmflexframegen_write_header(ofdmflexframegen _q, float complex * _buffer) { #if DEBUG_OFDMFLEXFRAMEGEN printf("writing header symbol\n"); #endif // load data onto data subcarriers unsigned int i; int sctype; for (i=0; i<_q->M; i++) { // sctype = _q->p[i]; // if (sctype == OFDMFRAME_SCTYPE_DATA) { // load... if (_q->header_symbol_index < OFDMFLEXFRAME_H_SYM) { // modulate header symbol onto data subcarrier modem_modulate(_q->mod_header, _q->header_mod[_q->header_symbol_index++], &_q->X[i]); //printf(" writing symbol %3u / %3u (x = %8.5f + j%8.5f)\n", _q->header_symbol_index, OFDMFLEXFRAME_H_SYM, crealf(_q->X[i]), cimagf(_q->X[i])); } else { //printf(" random header symbol\n"); // load random symbol unsigned int sym = modem_gen_rand_sym(_q->mod_payload); modem_modulate(_q->mod_payload, sym, &_q->X[i]); } } else { // ignore subcarrier (ofdmframegen handles nulls and pilots) _q->X[i] = 0.0f; } } // write symbol ofdmframegen_writesymbol(_q->fg, _q->X, _buffer); // check state if (_q->symbol_number == _q->num_symbols_header) { _q->symbol_number = 0; _q->state = OFDMFLEXFRAMEGEN_STATE_PAYLOAD; } }
// write payload symbol void ofdmflexframegen_write_payload(ofdmflexframegen _q, float complex * _buffer) { #if DEBUG_OFDMFLEXFRAMEGEN printf("writing payload symbol\n"); #endif // load data onto data subcarriers unsigned int i; int sctype; for (i=0; i<_q->M; i++) { // sctype = _q->p[i]; // if (sctype == OFDMFRAME_SCTYPE_DATA) { // load... if (_q->payload_symbol_index < _q->payload_mod_len) { // modulate payload symbol onto data subcarrier modem_modulate(_q->mod_payload, _q->payload_mod[_q->payload_symbol_index++], &_q->X[i]); } else { //printf(" random payload symbol\n"); // load random symbol unsigned int sym = modem_gen_rand_sym(_q->mod_payload); modem_modulate(_q->mod_payload, sym, &_q->X[i]); } } else { // ignore subcarrier (ofdmframegen handles nulls and pilots) _q->X[i] = 0.0f; } } // write symbol ofdmframegen_writesymbol(_q->fg, _q->X, _buffer); // check to see if this is the last symbol in the payload if (_q->symbol_number == _q->num_symbols_payload) _q->frame_complete = 1; }
int main(int argc, char*argv[]) { // options float noise_floor= -40.0f; // noise floor [dB] float SNRdB = 20.0f; // signal-to-noise ratio [dB] float bt = 0.05f; // loop bandwidth unsigned int num_symbols= 100; // number of iterations unsigned int d = 5; // print every d iterations unsigned int k = 2; // interpolation factor (samples/symbol) unsigned int m = 3; // filter delay (symbols) float beta = 0.3f; // filter excess bandwidth factor float dt = 0.0f; // filter fractional sample delay // derived values unsigned int num_samples=num_symbols*k; float gamma = powf(10.0f, (SNRdB+noise_floor)/20.0f); // channel gain float nstd = powf(10.0f, noise_floor / 20.0f); // arrays float complex x[num_samples]; float complex y[num_samples]; float rssi[num_samples]; // create objects modem mod = modem_create(LIQUID_MODEM_QPSK); firinterp_crcf interp = firinterp_crcf_create_prototype(LIQUID_FIRFILT_RRC,k,m,beta,dt); agc_crcf p = agc_crcf_create(); agc_crcf_set_bandwidth(p, bt); unsigned int i; // print info printf("automatic gain control // loop bandwidth: %4.2e\n",bt); unsigned int sym; float complex s; for (i=0; i<num_symbols; i++) { // generate random symbol sym = modem_gen_rand_sym(mod); modem_modulate(mod, sym, &s); s *= gamma; firinterp_crcf_execute(interp, s, &x[i*k]); } // add noise for (i=0; i<num_samples; i++) x[i] += nstd*(randnf() + _Complex_I*randnf()) * M_SQRT1_2; // run agc for (i=0; i<num_samples; i++) { agc_crcf_execute(p, x[i], &y[i]); rssi[i] = agc_crcf_get_rssi(p); } // destroy objects modem_destroy(mod); agc_crcf_destroy(p); firinterp_crcf_destroy(interp); // print results to screen printf("received signal strength indication (rssi):\n"); for (i=0; i<num_samples; i+=d) { printf("%4u : %8.2f\n", i, rssi[i]); } // // export results // 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\n",OUTPUT_FILENAME); fprintf(fid,"n = %u;\n", num_samples); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); for (i=0; i<num_samples; i++) { fprintf(fid," x(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); fprintf(fid," y(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(y[i]), cimagf(y[i])); fprintf(fid,"rssi(%4u) = %12.4e;\n", i+1, rssi[i]); } fprintf(fid,"\n\n"); fprintf(fid,"n = length(x);\n"); fprintf(fid,"t = 0:(n-1);\n"); fprintf(fid,"figure('position',[100 100 800 600]);\n"); fprintf(fid,"subplot(2,1,1);\n"); fprintf(fid," plot(t,rssi,'-k','LineWidth',2);\n"); fprintf(fid," xlabel('sample index');\n"); fprintf(fid," ylabel('rssi [dB]');\n"); fprintf(fid," grid on;\n"); fprintf(fid,"subplot(2,1,2);\n"); fprintf(fid," plot(t,real(y),t,imag(y));\n"); fprintf(fid," xlabel('sample index');\n"); fprintf(fid," ylabel('agc output');\n"); fprintf(fid," grid on;\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }
int main() { // options unsigned int num_channels=6; // for now, must be even number unsigned int num_symbols=32; // num symbols unsigned int m=2; // ofdm/oqam symbol delay float beta = 0.99f; // excess bandwidth factor float dt = 0.0f; // timing offset (fractional sample) modulation_scheme ms = LIQUID_MODEM_QAM4; // modulation scheme // number of frames (compensate for filter delay) unsigned int num_frames = num_symbols + 2*m; unsigned int num_samples = num_channels * num_frames; // create synthesizer/analyzer objects ofdmoqam cs = ofdmoqam_create(num_channels, m, beta, dt, LIQUID_SYNTHESIZER,0); ofdmoqam ca = ofdmoqam_create(num_channels, m, beta, dt, LIQUID_ANALYZER,0); // modem modem mod = modem_create(ms); FILE*fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s: auto-generated file\n\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\nclose all;\n\n"); fprintf(fid,"num_channels=%u;\n", num_channels); fprintf(fid,"num_symbols=%u;\n", num_symbols); fprintf(fid,"num_frames = %u;\n", num_frames); fprintf(fid,"num_samples = num_frames*num_channels;\n"); fprintf(fid,"X = zeros(%u,%u);\n", num_channels, num_frames); fprintf(fid,"y = zeros(1,%u);\n", num_samples); fprintf(fid,"Y = zeros(%u,%u);\n", num_channels, num_frames); unsigned int i, j, n=0; unsigned int s[num_symbols][num_channels]; float complex X[num_channels]; // channelized symbols float complex y[num_channels]; // interpolated time-domain samples float complex Y[num_channels]; // received symbols // generate random symbols for (i=0; i<num_symbols; i++) { for (j=0; j<num_channels; j++) { s[i][j] = modem_gen_rand_sym(mod); } } for (i=0; i<num_frames; i++) { // generate frame data for (j=0; j<num_channels; j++) { if (i<num_symbols) { modem_modulate(mod,s[i][j],&X[j]); } else { X[j] = 0.0f; } } // execute synthesyzer ofdmoqam_execute(cs, X, y); // channel // execute analyzer ofdmoqam_execute(ca, y, Y); // write output to file for (j=0; j<num_channels; j++) { // frequency data fprintf(fid,"X(%4u,%4u) = %12.4e + j*%12.4e;\n", j+1, i+1, crealf(X[j]), cimagf(X[j])); // time data fprintf(fid,"y(%4u) = %12.4e + j*%12.4e;\n", n+1, crealf(y[j]), cimag(y[j])); // received data fprintf(fid,"Y(%4u,%4u) = %12.4e + j*%12.4e;\n", j+1, i+1, crealf(Y[j]), cimagf(Y[j])); n++; } } // print results fprintf(fid,"\n\n"); fprintf(fid,"X0 = X(:,1:%u);\n", num_symbols); fprintf(fid,"Y0 = Y(:,%u:%u);\n", 2*m+1, num_symbols + 2*m); fprintf(fid,"for i=1:num_channels,\n"); fprintf(fid," figure;\n"); fprintf(fid," subplot(2,1,1);\n"); fprintf(fid," plot(1:num_symbols,real(X0(i,:)),'-x',1:num_symbols,real(Y0(i,:)),'-x');\n"); fprintf(fid," ylabel('Re');\n"); fprintf(fid," title(['channel ' num2str(i-1)]);\n"); fprintf(fid," subplot(2,1,2);\n"); fprintf(fid," plot(1:num_symbols,imag(X0(i,:)),'-x',1:num_symbols,imag(Y0(i,:)),'-x');\n"); fprintf(fid," ylabel('Im');\n"); fprintf(fid," pause(0.2);\n"); fprintf(fid,"end;\n"); // print results fprintf(fid,"\n\n"); fprintf(fid,"t = 0:(num_samples-1);\n"); fprintf(fid," figure;\n"); fprintf(fid," plot(t,real(y),'-', t,imag(y),'-');\n"); fprintf(fid," xlabel('time');\n"); fprintf(fid," ylabel('signal');\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); // destroy objects ofdmoqam_destroy(cs); ofdmoqam_destroy(ca); modem_destroy(mod); printf("done.\n"); return 0; }
// Helper function to keep code base small void ofdmframesync_rxsymbol_bench(struct rusage *_start, struct rusage *_finish, unsigned long int *_num_iterations, unsigned int _num_subcarriers, unsigned int _cp_len) { // options modulation_scheme ms = LIQUID_MODEM_QPSK; unsigned int M = _num_subcarriers; unsigned int cp_len = _cp_len; unsigned int taper_len = 0; // create synthesizer/analyzer objects ofdmframegen fg = ofdmframegen_create(M, cp_len, taper_len, NULL); //ofdmframegen_print(fg); modem mod = modem_create(ms); ofdmframesync fs = ofdmframesync_create(M,cp_len,taper_len,NULL,NULL,NULL); unsigned int i; float complex X[M]; // channelized symbol float complex x[M+cp_len]; // time-domain symbol // synchronize short sequence (first) ofdmframegen_write_S0a(fg, x); ofdmframesync_execute(fs, x, M+cp_len); // synchronize short sequence (second) ofdmframegen_write_S0b(fg, x); ofdmframesync_execute(fs, x, M+cp_len); // synchronize long sequence ofdmframegen_write_S1(fg, x); ofdmframesync_execute(fs, x, M+cp_len); // modulate data symbols (use same symbol, ignore pilot phase) unsigned int s; for (i=0; i<M; i++) { s = modem_gen_rand_sym(mod); modem_modulate(mod,s,&X[i]); } ofdmframegen_writesymbol(fg, X, x); // add noise for (i=0; i<M+cp_len; i++) x[i] += 0.02f*randnf()*cexpf(_Complex_I*2*M_PI*randf()); // normalize number of iterations *_num_iterations /= M; // start trials getrusage(RUSAGE_SELF, _start); for (i=0; i<(*_num_iterations); i++) { // receive data symbols (ignoring pilots) ofdmframesync_execute(fs, x, M+cp_len); ofdmframesync_execute(fs, x, M+cp_len); ofdmframesync_execute(fs, x, M+cp_len); ofdmframesync_execute(fs, x, M+cp_len); } getrusage(RUSAGE_SELF, _finish); *_num_iterations *= 4; // destroy objects ofdmframegen_destroy(fg); ofdmframesync_destroy(fs); modem_destroy(mod); }
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 = 0; // taper length unsigned int num_symbols = 1000; // number of data symbols modulation_scheme ms = LIQUID_MODEM_QPSK; // get options int dopt; while((dopt = getopt(argc,argv,"hM:C:T:N:")) != EOF){ switch (dopt) { case 'h': usage(); return 0; case 'M': M = atoi(optarg); break; case 'C': cp_len = atoi(optarg); break; case 'T': taper_len = atoi(optarg); break; case 'N': num_symbols = atoi(optarg); break; default: exit(1); } } unsigned int i; // derived values unsigned int frame_len = M + cp_len; // initialize subcarrier allocation unsigned char p[M]; ofdmframe_init_default_sctype(M, p); // create frame generator ofdmframegen fg = ofdmframegen_create(M, cp_len, taper_len, p); ofdmframegen_print(fg); modem mod = modem_create(ms); float complex X[M]; // channelized symbols float complex buffer[frame_len];// output time series float * PAPR = (float*) malloc(num_symbols*sizeof(float)); // histogram display float xmin = -1.29f + 0.70f*log2f(M); float xmax = 8.97f + 0.34f*log2f(M); unsigned int num_bins = 30; float bin_width = (xmax - xmin) / (num_bins); unsigned int hist[num_bins]; for (i=0; i<num_bins; i++) hist[i] = 0; // modulate data symbols unsigned int j; unsigned int s; float PAPR_min = 0.0f; float PAPR_max = 0.0f; float PAPR_mean = 0.0f; for (i=0; i<num_symbols; i++) { // data symbol for (j=0; j<M; j++) { s = modem_gen_rand_sym(mod); modem_modulate(mod,s,&X[j]); } // generate symbol ofdmframegen_writesymbol(fg, X, buffer); #if 0 // preamble if (i==0) ofdmframegen_write_S0a(fg, buffer); // S0 symbol (first) else if (i==1) ofdmframegen_write_S0b(fg, buffer); // S0 symbol (second) else if (i==2) ofdmframegen_write_S1( fg, buffer); // S1 symbol #endif // compute PAPR PAPR[i] = ofdmframe_PAPR(buffer, frame_len); // compute bin index unsigned int index; float ihat = num_bins * (PAPR[i] - xmin) / (xmax - xmin); if (ihat < 0.0f) index = 0; else index = (unsigned int)ihat; if (index >= num_bins) index = num_bins-1; hist[index]++; // save min/max PAPR values if (i==0 || PAPR[i] < PAPR_min) PAPR_min = PAPR[i]; if (i==0 || PAPR[i] > PAPR_max) PAPR_max = PAPR[i]; PAPR_mean += PAPR[i]; } PAPR_mean /= (float)num_symbols; // destroy objects ofdmframegen_destroy(fg); modem_destroy(mod); // print results to screen // find max(hist) unsigned int hist_max = 0; for (i=0; i<num_bins; i++) hist_max = hist[i] > hist_max ? hist[i] : hist_max; printf("%8s : %6s [%6s]\n", "PAPR[dB]", "count", "prob."); for (i=0; i<num_bins; i++) { printf("%8.2f : %6u [%6.4f]", xmin + i*bin_width, hist[i], (float)hist[i] / (float)num_symbols); unsigned int k; unsigned int n = round(60 * (float)hist[i] / (float)hist_max); for (k=0; k<n; k++) printf("#"); printf("\n"); } printf("\n"); printf("min PAPR: %12.4f dB\n", PAPR_min); printf("max PAPR: %12.4f dB\n", PAPR_max); printf("mean PAPR: %12.4f dB\n", PAPR_mean); // // export output file // // count subcarrier types unsigned int M_data = 0; unsigned int M_pilot = 0; unsigned int M_null = 0; ofdmframe_validate_sctype(p, M, &M_null, &M_pilot, &M_data); FILE * fid = fopen(OUTPUT_FILENAME,"w"); fprintf(fid,"%% %s: auto-generated file\n\n", OUTPUT_FILENAME); fprintf(fid,"clear all;\n"); fprintf(fid,"close all;\n\n"); fprintf(fid,"M = %u;\n", M); fprintf(fid,"M_data = %u;\n", M_data); fprintf(fid,"M_pilot = %u;\n", M_pilot); fprintf(fid,"M_null = %u;\n", M_null); fprintf(fid,"cp_len = %u;\n", cp_len); fprintf(fid,"num_symbols = %u;\n", num_symbols); fprintf(fid,"PAPR = zeros(1,num_symbols);\n"); for (i=0; i<num_symbols; i++) fprintf(fid," PAPR(%6u) = %12.4e;\n", i+1, PAPR[i]); fprintf(fid,"\n"); fprintf(fid,"figure;\n"); fprintf(fid,"hist(PAPR,25);\n"); fprintf(fid,"\n"); fprintf(fid,"figure;\n"); fprintf(fid,"cdf = [(1:num_symbols)-0.5]/num_symbols;\n"); fprintf(fid,"semilogy(sort(PAPR),1-cdf);\n"); fprintf(fid,"xlabel('PAPR [dB]');\n"); fprintf(fid,"ylabel('Complementary CDF');\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); // free allocated array free(PAPR); printf("done.\n"); return 0; }
int main(int argc, char*argv[]) { // options unsigned int bps=6; // bits per symbol unsigned int n=1024; // number of data points to evaluate int dopt; while ((dopt = getopt(argc,argv,"uhp:")) != EOF) { switch (dopt) { case 'u': case 'h': usage(); return 0; case 'p': bps = atoi(optarg); break; default: exit(1); } } // validate input if (bps == 0) { fprintf(stderr,"error: %s, bits/symbol must be greater than zero\n", argv[0]); exit(1); } // derived values unsigned int i; unsigned int M = 1<<bps; // constellation size // initialize constellation table float complex constellation[M]; // initialize constellation (spiral) for (i=0; i<M; i++) { float r = (float)i / logf((float)M) + 4.0f; float phi = (float)i / logf((float)M); constellation[i] = r * cexpf(_Complex_I*phi); } // create mod/demod objects modem mod = modem_create_arbitrary(constellation, M); modem demod = modem_create_arbitrary(constellation, M); modem_print(mod); // run simulation float complex x[n]; unsigned int num_errors = 0; // run simple BER simulation num_errors = 0; unsigned int sym_in; unsigned int sym_out; for (i=0; i<n; i++) { // generate and modulate random symbol sym_in = modem_gen_rand_sym(mod); modem_modulate(mod, sym_in, &x[i]); // add noise x[i] += 0.05 * randnf() * cexpf(_Complex_I*M_PI*randf()); // demodulate modem_demodulate(demod, x[i], &sym_out); // accumulate errors num_errors += count_bit_errors(sym_in,sym_out); } printf("num bit errors: %4u / %4u\n", num_errors, bps*n); // destroy modem objects modem_destroy(mod); modem_destroy(demod); // // 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"); fprintf(fid,"bps = %u;\n", bps); fprintf(fid,"M = %u;\n", M); for (i=0; i<n; i++) { fprintf(fid,"x(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i])); } // plot results fprintf(fid,"figure;\n"); fprintf(fid,"plot(x,'x','MarkerSize',1);\n"); fprintf(fid,"xlabel('in-phase');\n"); fprintf(fid,"ylabel('quadrature phase');\n"); fprintf(fid,"title(['Arbitrary ' num2str(M) '-QAM']);\n"); fprintf(fid,"axis([-1 1 -1 1]*1.9);\n"); fprintf(fid,"axis square;\n"); fprintf(fid,"grid on;\n"); fclose(fid); printf("results written to '%s'\n", OUTPUT_FILENAME); printf("done.\n"); return 0; }