Esempio n. 1
0
void SDRPostThread::updateActiveDemodulators() {
    // In range?
    std::vector<DemodulatorInstance *>::iterator demod_i;
    
    nRunDemods = 0;
    
    long long centerFreq = wxGetApp().getFrequency();
    
    for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
        DemodulatorInstance *demod = *demod_i;
        DemodulatorThreadInputQueue *demodQueue = demod->getIQInputDataPipe();
        
        // not in range?
        if (demod->isDeltaLock()) {
            if (demod->getFrequency() != centerFreq + demod->getDeltaLockOfs()) {
                demod->setFrequency(centerFreq + demod->getDeltaLockOfs());
                demod->updateLabel(demod->getFrequency());
                demod->setFollow(false);
                demod->setTracking(false);
            }
        }
        
        if (abs(frequency - demod->getFrequency()) > (sampleRate / 2)) {
            // deactivate if active
            if (demod->isActive() && !demod->isFollow() && !demod->isTracking()) {
                demod->setActive(false);
                DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData;
                dummyDataOut->frequency = frequency;
                dummyDataOut->sampleRate = sampleRate;
                demodQueue->push(dummyDataOut);
            }
            
            // follow if follow mode
            if (demod->isFollow() && centerFreq != demod->getFrequency()) {
                wxGetApp().setFrequency(demod->getFrequency());
                demod->setFollow(false);
            }
        } else if (!demod->isActive()) { // in range, activate if not activated
            demod->setActive(true);
            if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == NULL) {
                wxGetApp().getDemodMgr().setActiveDemodulator(demod);
            }
        }
        
        if (!demod->isActive()) {
            continue;
        }
        
        // Add to the current run
        if (nRunDemods == runDemods.size()) {
            runDemods.push_back(demod);
            demodChannel.push_back(-1);
        } else {
            runDemods[nRunDemods] = demod;
            demodChannel[nRunDemods] = -1;
        }
        nRunDemods++;
    }
}
Esempio n. 2
0
void SDRPostThread::run() {
#ifdef __APPLE__
    pthread_t tID = pthread_self();  // ID of this thread
    int priority = sched_get_priority_max( SCHED_FIFO) - 1;
    sched_param prio = {priority}; // scheduling priority of thread
    pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif

    dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);

    std::cout << "SDR post-processing thread started.." << std::endl;

    iqDataInQueue = (SDRThreadIQDataQueue*)getInputQueue("IQDataInput");
    iqDataOutQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQDataOutput");
    iqVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQVisualDataOutput");
    
    ReBuffer<DemodulatorThreadIQData> buffers;
    std::vector<liquid_float_complex> fpData;
    std::vector<liquid_float_complex> dataOut;
    
    iqDataInQueue->set_max_num_items(0);
    
    while (!terminated) {
        SDRThreadIQData *data_in;
        
        iqDataInQueue->pop(data_in);
        //        std::lock_guard < std::mutex > lock(data_in->m_mutex);
        
        if (data_in && data_in->data.size()) {
            int dataSize = data_in->data.size()/2;
            if (dataSize > fpData.capacity()) {
                fpData.reserve(dataSize);
                dataOut.reserve(dataSize);
            }
            if (dataSize != fpData.size()) {
                fpData.resize(dataSize);
                dataOut.resize(dataSize);
            }
            
            if (swapIQ) {
                for (int i = 0; i < dataSize; i++) {
                    fpData[i] = _lut_swap[*((uint16_t*)&data_in->data[2*i])];
                }
            } else {
                for (int i = 0; i < dataSize; i++) {
                    fpData[i] = _lut[*((uint16_t*)&data_in->data[2*i])];
                }
            }
            
            iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
            
            if (iqVisualQueue != NULL && !iqVisualQueue->full()) {
                DemodulatorThreadIQData *visualDataOut = visualDataBuffers.getBuffer();
                visualDataOut->setRefCount(1);
                
                int num_vis_samples = dataOut.size();

//                if (visualDataOut->data.size() < num_vis_samples) {
//                    if (visualDataOut->data.capacity() < num_vis_samples) {
//                        visualDataOut->data.reserve(num_vis_samples);
//                    }
//                    visualDataOut->data.resize(num_vis_samples);
//                }
//
                visualDataOut->frequency = data_in->frequency;
                visualDataOut->sampleRate = data_in->sampleRate;
                visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples);
                
                iqVisualQueue->push(visualDataOut);
            }
            
            busy_demod.lock();
            
            int activeDemods = 0;
            bool pushedData = false;
            
            if (demodulators.size() || iqDataOutQueue != NULL) {
                std::vector<DemodulatorInstance *>::iterator demod_i;
                for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
                    DemodulatorInstance *demod = *demod_i;
                    if (demod->getFrequency() != data_in->frequency
                        && abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
                        continue;
                    }
                    activeDemods++;
                }
                
                if (iqDataOutQueue != NULL) {
                    activeDemods++;
                }
                
                DemodulatorThreadIQData *demodDataOut = buffers.getBuffer();
                
                //                    std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
                demodDataOut->frequency = data_in->frequency;
                demodDataOut->sampleRate = data_in->sampleRate;
                demodDataOut->setRefCount(activeDemods);
                demodDataOut->data.assign(dataOut.begin(), dataOut.end());
                
                for (demod_i = demodulators.begin(); demod_i != demodulators.end(); demod_i++) {
                    DemodulatorInstance *demod = *demod_i;
                    DemodulatorThreadInputQueue *demodQueue = demod->getIQInputDataPipe();
                    
                    if (abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
                        if (demod->isActive() && !demod->isFollow() && !demod->isTracking()) {
                            demod->setActive(false);
                            DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData;
                            dummyDataOut->frequency = data_in->frequency;
                            dummyDataOut->sampleRate = data_in->sampleRate;
                            demodQueue->push(dummyDataOut);
                        }
                        
                        if (demod->isFollow() && wxGetApp().getFrequency() != demod->getFrequency()) {
                            wxGetApp().setFrequency(demod->getFrequency());
                        }
                    } else if (!demod->isActive()) {
                        demod->setActive(true);
                        if (wxGetApp().getDemodMgr().getLastActiveDemodulator() == NULL) {
                            wxGetApp().getDemodMgr().setActiveDemodulator(demod);
                        }
                    }
                    
                    if (!demod->isActive()) {
                        continue;
                    }
                    if (demod->isFollow()) {
                        demod->setFollow(false);
                    }
                    
                    demodQueue->push(demodDataOut);
                    pushedData = true;
                }
                
                if (iqDataOutQueue != NULL) {
                    if (!iqDataOutQueue->full()) {
                        iqDataOutQueue->push(demodDataOut);
                        pushedData = true;
                    } else {
                        demodDataOut->decRefCount();
                    }
                }
                
                if (!pushedData && iqDataOutQueue == NULL) {
                    demodDataOut->setRefCount(0);
                }
            }
            
            busy_demod.unlock();
        }
        data_in->decRefCount();
    }

//    buffers.purge();
    
    if (iqVisualQueue && !iqVisualQueue->empty()) {
        DemodulatorThreadIQData *visualDataDummy;
        iqVisualQueue->pop(visualDataDummy);
    }

//    visualDataBuffers.purge();

    std::cout << "SDR post-processing thread done." << std::endl;
}
Esempio n. 3
0
void AppFrame::OnIdle(wxIdleEvent& event) {
    bool work_done = false;

//#ifdef __APPLE__
//    std::this_thread::sleep_for(std::chrono::milliseconds(4));
//    std::this_thread::yield();
//#endif

    DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();

    if (demod) {
        DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();

        if (demod->isTracking()) {
            if (spectrumCanvas->getViewState()) {
                long long diff = abs(demod->getFrequency() - spectrumCanvas->getCenterFrequency()) + (demod->getBandwidth()/2) + (demod->getBandwidth()/4);

                if (diff > spectrumCanvas->getBandwidth()/2) {
                    if (demod->getBandwidth() > spectrumCanvas->getBandwidth()) {
                        diff = abs(demod->getFrequency() - spectrumCanvas->getCenterFrequency());
                    } else {
                        diff = diff - spectrumCanvas->getBandwidth()/2;
                    }
                    spectrumCanvas->moveCenterFrequency((demod->getFrequency() < spectrumCanvas->getCenterFrequency())?diff:-diff);
                    demod->setTracking(false);
                }
            } else {
                demod->setTracking(false);
            }
        }

        if (demod != activeDemodulator) {
            demodSignalMeter->setInputValue(demod->getSquelchLevel());
            demodGainMeter->setInputValue(demod->getGain());
            int outputDevice = demod->getOutputDevice();
            scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
            outputDeviceMenuItems[outputDevice]->Check(true);
            int dType = demod->getDemodulatorType();
            demodModeSelector->setSelection(dType);
        }
        if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
            long long centerFreq = demod->getFrequency();
            unsigned int demodBw = (unsigned int) ceil((float) demod->getBandwidth() * 2.25);

            if (demod->getDemodulatorType() == DEMOD_TYPE_USB) {
                demodBw /= 2;
                centerFreq += demod->getBandwidth() / 4;
            }

            if (demod->getDemodulatorType() == DEMOD_TYPE_LSB) {
                demodBw /= 2;
                centerFreq -= demod->getBandwidth() / 4;
            }

            if (demodBw > wxGetApp().getSampleRate() / 2) {
                demodBw = wxGetApp().getSampleRate() / 2;
            }
            if (demodBw < 20000) {
                demodBw = 20000;
            }

            if (centerFreq != demodWaterfallCanvas->getCenterFrequency()) {
                demodWaterfallCanvas->setCenterFrequency(centerFreq);
                demodSpectrumCanvas->setCenterFrequency(centerFreq);
            }
            int dSelection = demodModeSelector->getSelection();
            if (dSelection != -1 && dSelection != demod->getDemodulatorType()) {
                demod->setDemodulatorType(dSelection);
            }

            demodWaterfallCanvas->setBandwidth(demodBw);
            demodSpectrumCanvas->setBandwidth(demodBw);
        }
        demodSignalMeter->setLevel(demod->getSignalLevel());
        demodGainMeter->setLevel(demod->getGain());
        if (demodSignalMeter->inputChanged()) {
            demod->setSquelchLevel(demodSignalMeter->getInputValue());
        }
        if (demodGainMeter->inputChanged()) {
            demod->setGain(demodGainMeter->getInputValue());
            demodGainMeter->setLevel(demodGainMeter->getInputValue());
        }
        activeDemodulator = demod;
    } else {
        DemodulatorMgr *mgr = &wxGetApp().getDemodMgr();

        int dSelection = demodModeSelector->getSelection();
        if (dSelection != -1 && dSelection != mgr->getLastDemodulatorType()) {
            mgr->setLastDemodulatorType(dSelection);
        }
        demodGainMeter->setLevel(mgr->getLastGain());
        if (demodSignalMeter->inputChanged()) {
            mgr->setLastSquelchLevel(demodSignalMeter->getInputValue());
        }
        if (demodGainMeter->inputChanged()) {
            mgr->setLastGain(demodGainMeter->getInputValue());
            demodGainMeter->setLevel(demodGainMeter->getInputValue());
        }

        if (wxGetApp().getFrequency() != demodWaterfallCanvas->getCenterFrequency()) {
            demodWaterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
            demodSpectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
        }
        if (spectrumCanvas->getViewState() && abs(wxGetApp().getFrequency()-spectrumCanvas->getCenterFrequency()) > (wxGetApp().getSampleRate()/2)) {
            spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
            waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
        }
    }

    if (demodTuner->getMouseTracker()->mouseInView()) {
        if (!demodTuner->HasFocus()) {
            demodTuner->SetFocus();
        }
    } else if (!waterfallCanvas->HasFocus()) {
        waterfallCanvas->SetFocus();
    }

    scopeCanvas->setPPMMode(demodTuner->isAltDown());

    event.Skip();
}