Пример #1
0
// reset frame synchronizer object
void flexframesync_reset(flexframesync _q)
{
    // reset binary pre-demod synchronizer
    detector_cccf_reset(_q->frame_detector);

    // clear pre-demod buffer
    windowcf_clear(_q->buffer);

    // reset carrier recovery objects
    nco_crcf_reset(_q->nco_coarse);
    nco_crcf_reset(_q->nco_fine);

    // reset symbol timing recovery state
    firpfb_crcf_reset(_q->mf);
    firpfb_crcf_reset(_q->dmf);
    _q->pfb_q = 0.0f;   // filtered error signal
        
    // reset state
    _q->state           = STATE_DETECTFRAME;
    _q->pn_counter      = 0;
    _q->header_counter  = 0;
    _q->payload_counter = 0;
    
    // reset frame statistics
    _q->framestats.evm = 0.0f;
}
Пример #2
0
void ofdmframesync_reset(ofdmframesync _q)
{
#if 0
    // reset gain parameters
    unsigned int i;
    for (i=0; i<_q->M; i++)
        _q->G[i] = 1.0f;
#endif

    // reset synchronizer objects
    nco_crcf_reset(_q->nco_rx);
    msequence_reset(_q->ms_pilot);

    // reset timers
    _q->timer = 0;
    _q->num_symbols = 0;
    _q->s_hat_0 = 0.0f;
    _q->s_hat_1 = 0.0f;
    _q->phi_prime = 0.0f;
    _q->p1_prime = 0.0f;

    // set thresholds (increase for small number of subcarriers)
    _q->plcp_detect_thresh = (_q->M > 44) ? 0.35f : 0.35f + 0.01f*(44 - _q->M);
    _q->plcp_sync_thresh   = (_q->M > 44) ? 0.30f : 0.30f + 0.01f*(44 - _q->M);

    // reset state
    _q->state = OFDMFRAMESYNC_STATE_SEEKPLCP;
}
Пример #3
0
// reset frame synchronizer object
void gmskframesync_reset(gmskframesync _q)
{
    // reset state and counters
    _q->state = STATE_DETECTFRAME;
    _q->preamble_counter = 0;
    _q->header_counter   = 0;
    _q->payload_counter  = 0;
    
    // clear pre-demod buffer
    windowcf_clear(_q->buffer);

    // reset internal objects
    detector_cccf_reset(_q->frame_detector);
    
    // reset carrier recovery objects
    nco_crcf_reset(_q->nco_coarse);

    // reset sample state
    _q->x_prime = 0.0f;
    _q->fi_hat  = 0.0f;
    
    // reset symbol timing recovery state
    firpfb_rrrf_reset(_q->mf);
    firpfb_rrrf_reset(_q->dmf);
    _q->pfb_q = 0.0f;   // filtered error signal
        
}
Пример #4
0
ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
    ModemKitFMStereo *kit = new ModemKitFMStereo;
    
    kit->audioResampleRatio = double(audioSampleRate) / double(sampleRate);
    kit->sampleRate = sampleRate;
    kit->audioSampleRate = audioSampleRate;
   
    float As = 60.0f;         // stop-band attenuation [dB]
    
    kit->audioResampler = msresamp_rrrf_create(kit->audioResampleRatio, As);
    kit->stereoResampler = msresamp_rrrf_create(kit->audioResampleRatio, As);
    
    // Stereo filters / shifters
    double firStereoCutoff = 16000.0 / double(audioSampleRate);
    // filter transition
    float ft = 1000.0f / double(audioSampleRate);
    // fractional timing offset
    float mu = 0.0f;
    
    if (firStereoCutoff < 0) {
        firStereoCutoff = 0;
    }
    
    if (firStereoCutoff > 0.5) {
        firStereoCutoff = 0.5;
    }
    
    unsigned int h_len = estimate_req_filter_len(ft, As);
    float *h = new float[h_len];
    liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h);
    
    kit->firStereoLeft = firfilt_rrrf_create(h, h_len);
    kit->firStereoRight = firfilt_rrrf_create(h, h_len);
    
    // stereo pilot filter
    float bw = float(sampleRate);
    if (bw < 100000.0) {
        bw = 100000.0;
    }
    unsigned int order =   5;       // filter order
    float        f0    =   ((float) 19000 / bw);
    float        fc    =   ((float) 19500 / bw);
    float        Ap    =   1.0f;
    
    kit->iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As);
    
    kit->firStereoR2C = firhilbf_create(5, 60.0f);
    kit->firStereoC2R = firhilbf_create(5, 60.0f);
    
    kit->stereoPilot = nco_crcf_create(LIQUID_VCO);
    nco_crcf_reset(kit->stereoPilot);
    nco_crcf_pll_set_bandwidth(kit->stereoPilot, 0.25f);
    
    return kit;
}
Пример #5
0
// reset frame synchronizer object
void flexframesync_reset(flexframesync _q)
{
    // reset binary pre-demod synchronizer
    qdetector_cccf_reset(_q->detector);

    // reset carrier recovery objects
    nco_crcf_reset(_q->mixer);
    nco_crcf_reset(_q->pll);

    // reset symbol timing recovery state
    firpfb_crcf_reset(_q->mf);
        
    // reset state
    _q->state           = FLEXFRAMESYNC_STATE_DETECTFRAME;
    _q->preamble_counter= 0;
    _q->symbol_counter  = 0;
    
    // reset frame statistics
    _q->framesyncstats.evm = 0.0f;
}
Пример #6
0
void ofdmoqamframe64sync_reset(ofdmoqamframe64sync _q)
{
    // reset pilot sequence generator
    msequence_reset(_q->ms_pilot);

    // reset auto-correlators
    autocorr_cccf_clear(_q->autocorr);
    _q->rxx_mag_max = 0.0f;

    // reset frequency offset estimation, correction
    _q->nu_hat = 0.0f;
    nco_crcf_reset(_q->nco_rx);
    nco_crcf_reset(_q->nco_pilot);
    pll_reset(_q->pll_pilot);

    // clear input buffer
    windowcf_clear(_q->input_buffer);

    // clear analysis filter bank objects
    firpfbch_clear(_q->ca0);
    firpfbch_clear(_q->ca1);

    // reset gain parameters
    _q->g = 1.0f;   // coarse gain estimate
    unsigned int i;
    for (i=0; i<_q->num_subcarriers; i++)
        _q->G[i] = 1.0f;
    for (i=0; i<4; i++)
        _q->y_phase[i] = 0.0f;

    // reset state
    _q->state = OFDMOQAMFRAME64SYNC_STATE_PLCPSHORT;
    //_q->state = OFDMOQAMFRAME64SYNC_STATE_PLCPLONG0;
    _q->timer = 0;
    _q->num_symbols = 0;
    _q->num_data_symbols = 0;
    _q->num_samples = 0;
    _q->sample_phase = 0;
}
Пример #7
0
// reset WLAN framing synchronizer object internal state
void wlanframesync_reset(wlanframesync _q)
{
    // clear buffer
    windowcf_clear(_q->input_buffer);

    // reset NCO object
    nco_crcf_reset(_q->nco_rx);

    // reset timers/state
    _q->state = WLANFRAMESYNC_STATE_SEEKPLCP;
    _q->timer = 0;
    _q->num_symbols = 0;    // number of received OFDM data symbols
    _q->phi_prime = 0.0f;   // reset phase offset estimate

    // reset pilot sequence generator
    wlan_lfsr_reset(_q->ms_pilot);
}
Пример #8
0
// reset state
void fskmod_reset(fskmod _q)
{
    // reset internal objects
    nco_crcf_reset(_q->oscillator);
}
void SpectrumVisualProcessor::process() {
    if (!isOutputEmpty()) {
        return;
    }
    if (!input || input->empty()) {
        return;
    }
    
    DemodulatorThreadIQData *iqData;
    
    input->pop(iqData);
    
    if (!iqData) {
        return;
    }
    
    iqData->busy_rw.lock();
    busy_run.lock();
    
    std::vector<liquid_float_complex> *data = &iqData->data;
    
    if (data && data->size()) {
        SpectrumVisualData *output = outputBuffers.getBuffer();
        
        if (output->spectrum_points.size() < fftSize * 2) {
            output->spectrum_points.resize(fftSize * 2);
        }
        
        unsigned int num_written;
        
        if (is_view.load()) {
            if (!iqData->frequency || !iqData->sampleRate) {
                iqData->decRefCount();
                iqData->busy_rw.unlock();
                busy_run.unlock();
                return;
            }
            
            resamplerRatio = (double) (bandwidth) / (double) iqData->sampleRate;
            
            int desired_input_size = fftSize / resamplerRatio;
            
            this->desiredInputSize.store(desired_input_size);
            
            if (iqData->data.size() < desired_input_size) {
                //                std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl;
                desired_input_size = iqData->data.size();
            }
            
            if (centerFreq != iqData->frequency) {
                if ((centerFreq - iqData->frequency) != shiftFrequency || lastInputBandwidth != iqData->sampleRate) {
                    if (abs(iqData->frequency - centerFreq) < (wxGetApp().getSampleRate() / 2)) {
                        shiftFrequency = centerFreq - iqData->frequency;
                        nco_crcf_reset(freqShifter);
                        nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) iqData->sampleRate)));
                    }
                }
                
                if (shiftBuffer.size() != desired_input_size) {
                    if (shiftBuffer.capacity() < desired_input_size) {
                        shiftBuffer.reserve(desired_input_size);
                    }
                    shiftBuffer.resize(desired_input_size);
                }
                
                if (shiftFrequency < 0) {
                    nco_crcf_mix_block_up(freqShifter, &iqData->data[0], &shiftBuffer[0], desired_input_size);
                } else {
                    nco_crcf_mix_block_down(freqShifter, &iqData->data[0], &shiftBuffer[0], desired_input_size);
                }
            } else {
                shiftBuffer.assign(iqData->data.begin(), iqData->data.end());
            }
            
            if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != iqData->sampleRate) {
                float As = 60.0f;
                
                if (resampler) {
                    msresamp_crcf_destroy(resampler);
                }
                resampler = msresamp_crcf_create(resamplerRatio, As);
                
                lastBandwidth = bandwidth;
                lastInputBandwidth = iqData->sampleRate;
            }
            
            
            int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512;
            
            if (resampleBuffer.size() != out_size) {
                if (resampleBuffer.capacity() < out_size) {
                    resampleBuffer.reserve(out_size);
                }
                resampleBuffer.resize(out_size);
            }
            
            
            msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written);
            
            resampleBuffer.resize(fftSize);
            
            if (num_written < fftSize) {
                for (int i = 0; i < num_written; i++) {
                    fftInData[i][0] = resampleBuffer[i].real;
                    fftInData[i][1] = resampleBuffer[i].imag;
                }
                for (int i = num_written; i < fftSize; i++) {
                    fftInData[i][0] = 0;
                    fftInData[i][1] = 0;
                }
            } else {
                for (int i = 0; i < fftSize; i++) {
                    fftInData[i][0] = resampleBuffer[i].real;
                    fftInData[i][1] = resampleBuffer[i].imag;
                }
            }
        } else {
            num_written = data->size();
            if (data->size() < fftSize) {
                for (int i = 0, iMax = data->size(); i < iMax; i++) {
                    fftInData[i][0] = (*data)[i].real;
                    fftInData[i][1] = (*data)[i].imag;
                }
                for (int i = data->size(); i < fftSize; i++) {
                    fftInData[i][0] = 0;
                    fftInData[i][1] = 0;
                }
            } else {
                for (int i = 0; i < fftSize; i++) {
                    fftInData[i][0] = (*data)[i].real;
                    fftInData[i][1] = (*data)[i].imag;
                }
            }
        }
        
        bool execute = false;
        
        if (num_written >= fftSize) {
            execute = true;
            memcpy(fftwInput, fftInData, fftSize * sizeof(fftwf_complex));
            memcpy(fftLastData, fftwInput, fftSize * sizeof(fftwf_complex));
            
        } else {
            if (lastDataSize + num_written < fftSize) { // priming
                unsigned int num_copy = fftSize - lastDataSize;
                if (num_written > num_copy) {
                    num_copy = num_written;
                }
                memcpy(fftLastData, fftInData, num_copy * sizeof(fftwf_complex));
                lastDataSize += num_copy;
            } else {
                unsigned int num_last = (fftSize - num_written);
                memcpy(fftwInput, fftLastData + (lastDataSize - num_last), num_last * sizeof(fftwf_complex));
                memcpy(fftwInput + num_last, fftInData, num_written * sizeof(fftwf_complex));
                memcpy(fftLastData, fftwInput, fftSize * sizeof(fftwf_complex));
                execute = true;
            }
        }
        
        if (execute) {
            fftwf_execute(fftw_plan);
            
            float fft_ceil = 0, fft_floor = 1;
            
            if (fft_result.size() < fftSize) {
                fft_result.resize(fftSize);
                fft_result_ma.resize(fftSize);
                fft_result_maa.resize(fftSize);
            }
            
            for (int i = 0, iMax = fftSize / 2; i < iMax; i++) {
                float a = fftwOutput[i][0];
                float b = fftwOutput[i][1];
                float c = sqrt(a * a + b * b);
                
                float x = fftwOutput[fftSize / 2 + i][0];
                float y = fftwOutput[fftSize / 2 + i][1];
                float z = sqrt(x * x + y * y);
                
                fft_result[i] = (z);
                fft_result[fftSize / 2 + i] = (c);
            }
            
            for (int i = 0, iMax = fftSize; i < iMax; i++) {
                if (is_view.load()) {
                    fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * fft_average_rate;
                    fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * fft_average_rate;
                } else {
                    fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * fft_average_rate;
                    fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * fft_average_rate;
                }
                
                if (fft_result_maa[i] > fft_ceil) {
                    fft_ceil = fft_result_maa[i];
                }
                if (fft_result_maa[i] < fft_floor) {
                    fft_floor = fft_result_maa[i];
                }
            }
            
            fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05;
            fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05;
            
            fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05;
            fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05;
            
            float sf = scaleFactor.load();
            
            for (int i = 0, iMax = fftSize; i < iMax; i++) {
                float v = (log10(fft_result_maa[i]+0.25 - (fft_floor_maa-0.75)) / log10((fft_ceil_maa+0.25) - (fft_floor_maa-0.75)));
                output->spectrum_points[i * 2] = ((float) i / (float) iMax);
                output->spectrum_points[i * 2 + 1] = v*sf;
            }
                
            if (hideDC.load()) { // DC-spike removal
                long long freqMin = centerFreq-(bandwidth/2);
                long long freqMax = centerFreq+(bandwidth/2);
                long long zeroPt = (iqData->frequency-freqMin);
                
                if (freqMin < iqData->frequency && freqMax > iqData->frequency) {
                    int freqRange = int(freqMax-freqMin);
                    int freqStep = freqRange/fftSize;
                    int fftStart = (zeroPt/freqStep)-(2000/freqStep);
                    int fftEnd = (zeroPt/freqStep)+(2000/freqStep);
                    
//                    std::cout << "range:" << freqRange << ", step: " << freqStep << ", start: " << fftStart << ", end: " << fftEnd << std::endl;
                    
                    if (fftEnd-fftStart < 2) {
                        fftEnd++;
                        fftStart--;
                    }
                    
                    int numSteps = (fftEnd-fftStart);
                    int halfWay = fftStart+(numSteps/2);

                    if ((fftEnd+numSteps/2+1 < fftSize) && (fftStart-numSteps/2-1 >= 0) && (fftEnd > fftStart)) {
                        int n = 1;
                        for (int i = fftStart; i < halfWay; i++) {
                            output->spectrum_points[i * 2 + 1] = output->spectrum_points[(fftStart - n) * 2 + 1];
                            n++;
                        }
                        n = 1;
                        for (int i = halfWay; i < fftEnd; i++) {
                            output->spectrum_points[i * 2 + 1] = output->spectrum_points[(fftEnd + n) * 2 + 1];
                            n++;
                        }
                    }
                }
            }
            
            output->fft_ceiling = fft_ceil_maa/sf;
            output->fft_floor = fft_floor_maa;
        }
        
        distribute(output);
    }
 
    iqData->decRefCount();
    iqData->busy_rw.unlock();
    busy_run.unlock();
}