Пример #1
0
// Help function to keep code base small
void modem_test_demodsoft(modulation_scheme _ms)
{
    // generate mod/demod
    modem mod   = modem_create(_ms);
    modem demod = modem_create(_ms);

    // 
    unsigned int bps = modem_get_bps(demod);

    // run the test
    unsigned int i, s, M=1<<bps;
    unsigned int sym_soft;
    unsigned char soft_bits[bps];
    float complex x;
    
    for (i=0; i<M; i++) {
        // modulate symbol
        modem_modulate(mod, i, &x);

        // demodulate using soft-decision
        modem_demodulate_soft(demod, x, &s, soft_bits);

        // check hard-decision output
        CONTEND_EQUALITY(s, i);

        // check soft bits
        liquid_pack_soft_bits(soft_bits, bps, &sym_soft);
        CONTEND_EQUALITY(sym_soft, i);

        // check phase error, evm, etc.
        //CONTEND_DELTA( modem_get_demodulator_phase_error(demod), 0.0f, 1e-3f);
        //CONTEND_DELTA( modem_get_demodulator_evm(demod), 0.0f, 1e-3f);
    }
    // clean it up
    modem_destroy(mod);
    modem_destroy(demod);
}
Пример #2
0
// receive header data
void ofdmflexframesync_rxheader(ofdmflexframesync _q,
                                float complex * _X)
{
#if DEBUG_OFDMFLEXFRAMESYNC
    printf("  ofdmflexframesync extracting header...\n");
#endif

    // demodulate header symbols
    unsigned int i;
    int sctype;
    for (i=0; i<_q->M; i++) {
        // subcarrier type (PILOT/NULL/DATA)
        sctype = _q->p[i];

        // ignore pilot and null subcarriers
        if (sctype == OFDMFRAME_SCTYPE_DATA) {
            // unload header symbols
            // demodulate header symbol
            unsigned int sym;
#if OFDMFLEXFRAME_H_SOFT
            modem_demodulate_soft(_q->mod_header, _X[i], &sym, &_q->header_mod[OFDMFLEXFRAME_H_BPS*_q->header_symbol_index]);
#else
            modem_demodulate(_q->mod_header, _X[i], &sym);
            _q->header_mod[_q->header_symbol_index] = sym;
#endif
            _q->header_symbol_index++;
            //printf("  extracting symbol %3u / %3u (x = %8.5f + j%8.5f)\n", _q->header_symbol_index, OFDMFLEXFRAME_H_SYM, crealf(_X[i]), cimagf(_X[i]));

            // get demodulator error vector magnitude
            float evm = modem_get_demodulator_evm(_q->mod_header);
            _q->evm_hat += evm*evm;

            // header extracted
            if (_q->header_symbol_index == OFDMFLEXFRAME_H_SYM) {
                // decode header
                ofdmflexframesync_decode_header(_q);

                // compute error vector magnitude estimate
                _q->framestats.evm = 10*log10f( _q->evm_hat/OFDMFLEXFRAME_H_SYM );

                // invoke callback if header is invalid
                if (_q->header_valid)
                    _q->state = OFDMFLEXFRAMESYNC_STATE_PAYLOAD;
                else {
                    //printf("**** header invalid!\n");
                    // set framestats internals
                    _q->framestats.rssi             = ofdmframesync_get_rssi(_q->fs);
                    _q->framestats.cfo              = ofdmframesync_get_cfo(_q->fs);
                    _q->framestats.framesyms        = NULL;
                    _q->framestats.num_framesyms    = 0;
                    _q->framestats.mod_scheme       = LIQUID_MODEM_UNKNOWN;
                    _q->framestats.mod_bps          = 0;
                    _q->framestats.check            = LIQUID_CRC_UNKNOWN;
                    _q->framestats.fec0             = LIQUID_FEC_UNKNOWN;
                    _q->framestats.fec1             = LIQUID_FEC_UNKNOWN;

                    // invoke callback method
                    _q->callback(_q->header,
                                 _q->header_valid,
                                 NULL,
                                 0,
                                 0,
                                 _q->framestats,
                                 _q->userdata);

                    ofdmflexframesync_reset(_q);
                }
                break;
            }
        }
    }
}
Пример #3
0
// execute synchronizer, receiving header
//  _q      :   frame synchronizer object
//  _x      :   input sample
void flexframesync_execute_rxheader(flexframesync _q,
                                    float complex _x)
{
    // mix signal down
    float complex y;
    nco_crcf_mix_down(_q->nco_coarse, _x*0.5f/_q->gamma_hat, &y);
    nco_crcf_step(_q->nco_coarse);

    // update symbol synchronizer
    float complex mf_out = 0.0f;
    int sample_available = flexframesync_update_symsync(_q, y, &mf_out);

    // compute output if timeout
    if (sample_available) {
        // push through fine-tuned nco
        nco_crcf_mix_down(_q->nco_fine, mf_out, &mf_out);

#if DEBUG_FLEXFRAMESYNC
        if (_q->debug_enabled)
            _q->header_sym[_q->header_counter] = mf_out;
#endif
        
        // demodulate
        unsigned int sym_out = 0;
#if DEMOD_HEADER_SOFT
        unsigned char bpsk_soft_bit = 0;
        modem_demodulate_soft(_q->demod_header, mf_out, &sym_out, &bpsk_soft_bit);
        _q->header_mod[_q->header_counter] = bpsk_soft_bit;
#else
        modem_demodulate(_q->demod_header, mf_out, &sym_out);
        _q->header_mod[_q->header_counter] = (unsigned char)sym_out;
#endif

        // update phase-locked loop and fine-tuned NCO
        float phase_error = modem_get_demodulator_phase_error(_q->demod_header);
        nco_crcf_pll_step(_q->nco_fine, phase_error);
        nco_crcf_step(_q->nco_fine);

        // update error vector magnitude
        float evm = modem_get_demodulator_evm(_q->demod_header);
        _q->framestats.evm += evm*evm;

        // increment counter
        _q->header_counter++;

        if (_q->header_counter == FLEXFRAME_H_SYM) {
            // decode header and invoke callback
            flexframesync_decode_header(_q);
            
            // invoke callback if header is invalid
            if (!_q->header_valid && _q->callback != NULL) {
                // set framestats internals
                _q->framestats.evm           = 20*log10f(sqrtf(_q->framestats.evm / FLEXFRAME_H_SYM));
                _q->framestats.rssi          = 20*log10f(_q->gamma_hat);
                _q->framestats.cfo           = nco_crcf_get_frequency(_q->nco_coarse) +
                                               nco_crcf_get_frequency(_q->nco_fine) / 2.0f; //(float)(_q->k);
                _q->framestats.framesyms     = NULL;
                _q->framestats.num_framesyms = 0;
                _q->framestats.mod_scheme    = LIQUID_MODEM_UNKNOWN;
                _q->framestats.mod_bps       = 0;
                _q->framestats.check         = LIQUID_CRC_UNKNOWN;
                _q->framestats.fec0          = LIQUID_FEC_UNKNOWN;
                _q->framestats.fec1          = LIQUID_FEC_UNKNOWN;

                // invoke callback method
                _q->callback(_q->header,
                             _q->header_valid,
                             NULL,
                             0,
                             0,
                             _q->framestats,
                             _q->userdata);
            }
            
            if (!_q->header_valid) {
                flexframesync_reset(_q);
                return;
            }

            
            // update state
            _q->state = STATE_RXPAYLOAD;
        }
    }
}