// generate short sequence symbols
//  _p      :   subcarrier allocation array
//  _M      :   total number of subcarriers
//  _S0     :   output symbol (freq)
//  _s0     :   output symbol (time)
//  _M_S0   :   total number of enabled subcarriers in S0
void ofdmframe_init_S0(unsigned char * _p,
                       unsigned int    _M,
                       float complex * _S0,
                       float complex * _s0,
                       unsigned int *  _M_S0)
{
    unsigned int i;

    // compute m-sequence length
    unsigned int m = liquid_nextpow2(_M);
    if (m < 4)      m = 4;
    else if (m > 8) m = 8;

    // generate m-sequence generator object
    msequence ms = msequence_create_default(m);

    unsigned int s;
    unsigned int M_S0 = 0;

    // short sequence
    for (i=0; i<_M; i++) {
        // generate symbol
        //s = msequence_generate_symbol(ms,1);
        s = msequence_generate_symbol(ms,3) & 0x01;

        if (_p[i] == OFDMFRAME_SCTYPE_NULL) {
            // NULL subcarrier
            _S0[i] = 0.0f;
        } else {
            if ( (i%2) == 0 ) {
                // even subcarrer
                _S0[i] = s ? 1.0f : -1.0f;
                M_S0++;
            } else {
                // odd subcarrer (ignore)
                _S0[i] = 0.0f;
            }
        }
    }

    // destroy objects
    msequence_destroy(ms);

    // ensure at least one subcarrier was enabled
    if (M_S0 == 0) {
        fprintf(stderr,"error: ofdmframe_init_S0(), no subcarriers enabled; check allocation\n");
        exit(1);
    }

    // set return value(s)
    *_M_S0 = M_S0;

    // run inverse fft to get time-domain sequence
    fft_run(_M, _S0, _s0, FFT_REVERSE, 0);

    // normalize time-domain sequence level
    float g = 1.0f / sqrtf(M_S0);
    for (i=0; i<_M; i++)
        _s0[i] *= g;
}
Example #2
0
// 
// autotest helper function
//
void validate_crc(crc_scheme _check,
                  unsigned int _n)
{
    unsigned int i;

    // generate pseudo-random data
    unsigned char data[_n];
    msequence ms = msequence_create_default(9);
    for (i=0; i<_n; i++)
        data[i] = msequence_generate_symbol(ms,8);
    msequence_destroy(ms);

    // generate key
    unsigned int key = crc_generate_key(_check, data, _n);

    // contend data/key are valid
    CONTEND_EXPRESSION(crc_validate_message(_check, data, _n, key));

    //
    unsigned char data_corrupt[_n];
    unsigned int j;
    for (i=0; i<_n; i++) {
        for (j=0; j<8; j++) {
            // copy original data sequence
            memmove(data_corrupt, data, _n*sizeof(unsigned char));

            // flip bit j at byte i
            data[i] ^= (1 << j);

            // contend data/key are invalid
            CONTEND_EXPRESSION(crc_validate_message(_check, data, _n, key)==0);
        }
    }
}
// generate long sequence symbols
//  _p      :   subcarrier allocation array
//  _M      :   total number of subcarriers
//  _S1     :   output symbol (freq)
//  _s1     :   output symbol (time)
//  _M_S1   :   total number of enabled subcarriers in S1
void ofdmframe_init_S1(unsigned char * _p,
                       unsigned int    _M,
                       float complex * _S1,
                       float complex * _s1,
                       unsigned int *  _M_S1)
{
    unsigned int i;

    // compute m-sequence length
    unsigned int m = liquid_nextpow2(_M);
    if (m < 4)      m = 4;
    else if (m > 8) m = 8;

    // increase m such that the resulting S1 sequence will
    // differ significantly from S0 with the same subcarrier
    // allocation array
    m++;

    // generate m-sequence generator object
    msequence ms = msequence_create_default(m);

    unsigned int s;
    unsigned int M_S1 = 0;

    // long sequence
    for (i=0; i<_M; i++) {
        // generate symbol
        //s = msequence_generate_symbol(ms,1);
        s = msequence_generate_symbol(ms,3) & 0x01;

        if (_p[i] == OFDMFRAME_SCTYPE_NULL) {
            // NULL subcarrier
            _S1[i] = 0.0f;
        } else {
            _S1[i] = s ? 1.0f : -1.0f;
            M_S1++;
        }
    }

    // destroy objects
    msequence_destroy(ms);

    // ensure at least one subcarrier was enabled
    if (M_S1 == 0) {
        fprintf(stderr,"error: ofdmframe_init_S1(), no subcarriers enabled; check allocation\n");
        exit(1);
    }

    // set return value(s)
    *_M_S1 = M_S1;

    // run inverse fft to get time-domain sequence
    fft_run(_M, _S1, _s1, FFT_REVERSE, 0);

    // normalize time-domain sequence level
    float g = 1.0f / sqrtf(M_S1);
    for (i=0; i<_M; i++)
        _s1[i] *= g;
}
// generate long sequence symbols
//  _p                  :   subcarrier allocation array
//  _num_subcarriers    :   total number of subcarriers
//  _S1                 :   output symbol
//  _M_S1               :   total number of enabled subcarriers in S1
void ofdmoqamframe_init_S1(unsigned char * _p,
                           unsigned int _num_subcarriers,
                           float complex * _S1,
                           unsigned int * _M_S1)
{
    unsigned int i;

    // compute m-sequence length
    unsigned int m = liquid_nextpow2(_num_subcarriers);
    if (m < 4)      m = 4;
    else if (m > 8) m = 8;

    // increase m such that the resulting S1 sequence will
    // differ significantly from S0 with the same subcarrier
    // allocation array
    m++;

    // generate m-sequence generator object
    msequence ms = msequence_create_default(m);

    unsigned int s;
    unsigned int M_S1 = 0;

    // long sequence
    for (i=0; i<_num_subcarriers; i++) {
        // generate symbol
        //s = msequence_generate_symbol(ms,1);
        s = msequence_generate_symbol(ms,3) & 0x01;

        if (_p[i] == OFDMOQAMFRAME_SCTYPE_NULL) {
            // NULL subcarrier
            _S1[i] = 0.0f;
        } else {
            _S1[i] = s ? 1.0f : -1.0f;
            M_S1++;

            // rotate by pi/2 on odd subcarriers
            _S1[i] *= (i%2)==0 ? 1.0f : _Complex_I;
        }
    }

    // destroy objects
    msequence_destroy(ms);

    // ensure at least one subcarrier was enabled
    if (M_S1 == 0) {
        fprintf(stderr,"error: ofdmoqamframe_init_S1(), no subcarriers enabled; check allocation\n");
        exit(1);
    }

    // set return value(s)
    *_M_S1 = M_S1;
}
// generate short sequence symbols
//  _p                  :   subcarrier allocation array
//  _num_subcarriers    :   total number of subcarriers
//  _S0                 :   output symbol
//  _M_S0               :   total number of enabled subcarriers in S0
void ofdmoqamframe_init_S0(unsigned char * _p,
                           unsigned int _num_subcarriers,
                           float complex * _S0,
                           unsigned int * _M_S0)
{
    unsigned int i;

    // compute m-sequence length
    unsigned int m = liquid_nextpow2(_num_subcarriers);
    if (m < 4)      m = 4;
    else if (m > 8) m = 8;

    // generate m-sequence generator object
    msequence ms = msequence_create_default(m);

    unsigned int s;
    unsigned int M_S0 = 0;

    // short sequence
    for (i=0; i<_num_subcarriers; i++) {
        // generate symbol
        //s = msequence_generate_symbol(ms,1);
        s = msequence_generate_symbol(ms,3) & 0x01;

        if (_p[i] == OFDMOQAMFRAME_SCTYPE_NULL) {
            // NULL subcarrier
            _S0[i] = 0.0f;
        } else {
            if ( (i%2) == 0 ) {
                // even subcarrer
                _S0[i] = s ? 1.0f : -1.0f;
                M_S0++;
            } else {
                // odd subcarrer (ignore)
                _S0[i] = 0.0f;
            }
        }
    }

    // destroy objects
    msequence_destroy(ms);

    // ensure at least one subcarrier was enabled
    if (M_S0 == 0) {
        fprintf(stderr,"error: ofdmoqamframe_init_S0(), no subcarriers enabled; check allocation\n");
        exit(1);
    }

    // set return value(s)
    *_M_S0 = M_S0;
}
// Helper function to keep code base small
void symsync_crcf_bench(struct rusage *     _start,
                        struct rusage *     _finish,
                        unsigned long int * _num_iterations,
                        unsigned int        _k,
                        unsigned int        _m)
{
    unsigned long int i;
    unsigned int npfb = 16;     // number of filters in bank
    unsigned int k    = _k;     // samples/symbol
    unsigned int m    = _m;     // filter delay [symbols]
    float beta        = 0.3f;   // filter excess bandwidth factor

    // create symbol synchronizer
    symsync_crcf q = symsync_crcf_create_rnyquist(LIQUID_RNYQUIST_RRC,
                                                  k, m, beta, npfb);

    //
    unsigned int num_samples = 64;
    *_num_iterations /= num_samples;

    unsigned int num_written;
    float complex x[num_samples];
    float complex y[num_samples];

    // generate pseudo-random data
    msequence ms = msequence_create_default(6);
    for (i=0; i<num_samples; i++)
        x[i] = ((float)msequence_generate_symbol(ms, 6) - 31.5) / 24.0f;
    msequence_destroy(ms);

    // start trials
    getrusage(RUSAGE_SELF, _start);
    for (i=0; i<(*_num_iterations); i++) {
        symsync_crcf_execute(q, x, num_samples, y, &num_written);
        symsync_crcf_execute(q, x, num_samples, y, &num_written);
        symsync_crcf_execute(q, x, num_samples, y, &num_written);
        symsync_crcf_execute(q, x, num_samples, y, &num_written);
    }
    getrusage(RUSAGE_SELF, _finish);
    *_num_iterations *= 4 * num_samples;

    symsync_crcf_destroy(q);
}