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);
}
예제 #2
0
// 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;
    }
}
예제 #3
0
// 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;
}
예제 #4
0
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;
}
예제 #5
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);
}
예제 #7
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   = 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;
}
예제 #8
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;
}