diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 662d882..d6ae6fc 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -671,8 +671,6 @@ void AppFrame::OnIdle(wxIdleEvent& event) { 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); @@ -816,7 +814,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) { wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0)); wxGetApp().getScopeProcessor()->run(); - wxGetApp().getSpectrumDistributor()->run(); +// wxGetApp().getSpectrumDistributor()->run(); SpectrumVisualProcessor *proc = wxGetApp().getSpectrumProcessor(); diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 15e411c..141e02b 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -59,22 +59,14 @@ bool CubicSDR::OnInit() { pipeIQVisualData = new DemodulatorThreadInputQueue(); pipeIQVisualData->set_max_num_items(1); - spectrumDistributor.setInput(pipeIQVisualData); - pipeDemodIQVisualData = new DemodulatorThreadInputQueue(); pipeDemodIQVisualData->set_max_num_items(1); - pipeSpectrumIQVisualData = new DemodulatorThreadInputQueue(); - pipeSpectrumIQVisualData->set_max_num_items(1); - pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue(); pipeWaterfallIQVisualData->set_max_num_items(128); - spectrumDistributor.attachOutput(pipeDemodIQVisualData); - spectrumDistributor.attachOutput(pipeSpectrumIQVisualData); - getDemodSpectrumProcessor()->setInput(pipeDemodIQVisualData); - getSpectrumProcessor()->setInput(pipeSpectrumIQVisualData); + getSpectrumProcessor()->setInput(pipeIQVisualData); pipeAudioVisualData = new DemodulatorThreadOutputQueue(); pipeAudioVisualData->set_max_num_items(1); @@ -89,19 +81,17 @@ bool CubicSDR::OnInit() { sdrThread->setOutputQueue("IQDataOutput",pipeSDRIQData); sdrPostThread = new SDRPostThread(); -// sdrPostThread->setNumVisSamples(BUF_SIZE); sdrPostThread->setInputQueue("IQDataInput", pipeSDRIQData); sdrPostThread->setOutputQueue("IQVisualDataOutput", pipeIQVisualData); sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData); + sdrPostThread->setOutputQueue("IQActiveDemodVisualDataOutput", pipeDemodIQVisualData); t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread); t_SpectrumVisual = new std::thread(&SpectrumVisualDataThread::threadMain, spectrumVisualThread); t_DemodVisual = new std::thread(&SpectrumVisualDataThread::threadMain, demodVisualThread); -// t_SDR = new std::thread(&SDRThread::threadMain, sdrThread); sdrEnum = new SDREnumerator(); - appframe = new AppFrame(); t_SDREnum = new std::thread(&SDREnumerator::threadMain, sdrEnum); @@ -371,11 +361,6 @@ SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() { return demodVisualThread->getProcessor(); } -VisualDataDistributor *CubicSDR::getSpectrumDistributor() { - return &spectrumDistributor; -} - - DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { return pipeAudioVisualData; } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index f892fdd..f7d7b9a 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -70,11 +70,11 @@ public: ScopeVisualProcessor *getScopeProcessor(); SpectrumVisualProcessor *getSpectrumProcessor(); SpectrumVisualProcessor *getDemodSpectrumProcessor(); - VisualDataDistributor *getSpectrumDistributor(); DemodulatorThreadOutputQueue* getAudioVisualQueue(); DemodulatorThreadInputQueue* getIQVisualQueue(); DemodulatorThreadInputQueue* getWaterfallVisualQueue(); + DemodulatorThreadInputQueue* getActiveDemodVisualQueue(); DemodulatorMgr &getDemodMgr(); void bindDemodulator(DemodulatorInstance *demod); @@ -122,18 +122,15 @@ private: SpectrumVisualDataThread *spectrumVisualThread; SpectrumVisualDataThread *demodVisualThread; -// SDRThreadCommandQueue* pipeSDRCommand; SDRThreadIQDataQueue* pipeSDRIQData; DemodulatorThreadInputQueue* pipeIQVisualData; DemodulatorThreadOutputQueue* pipeAudioVisualData; DemodulatorThreadInputQueue* pipeDemodIQVisualData; - DemodulatorThreadInputQueue* pipeSpectrumIQVisualData; DemodulatorThreadInputQueue* pipeWaterfallIQVisualData; + DemodulatorThreadInputQueue* pipeActiveDemodIQVisualData; ScopeVisualProcessor scopeProcessor; - VisualDataDistributor spectrumDistributor; - SDRDevicesDialog *deviceSelectorDialog; std::thread *t_SDR, *t_SDREnum, *t_PostSDR, *t_SpectrumVisual, *t_DemodVisual; diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 0822aed..74175e9 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -18,6 +18,7 @@ SDRPostThread::SDRPostThread() : IOThread() { nRunDemods = 0; doRefresh.store(false); + dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); } SDRPostThread::~SDRPostThread() { @@ -65,9 +66,7 @@ void SDRPostThread::initPFBChannelizer() { chanCenters.resize(numChannels); demodChannelActive.resize(numChannels); - // firpfbch2 returns 2x sample rate per channel - // so, max demodulation without gaps is 1/2 chanBw ..? -// std::cout << "Channel bandwidth spacing: " << (chanBw/2) << " actual bandwidth: " << chanBw << std::endl; +// std::cout << "Channel bandwidth spacing: " << (chanBw) << std::endl; } void SDRPostThread::updateActiveDemodulators() { @@ -141,8 +140,11 @@ void SDRPostThread::run() { iqDataInQueue = (SDRThreadIQDataQueue*)getInputQueue("IQDataInput"); iqDataOutQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQDataOutput"); iqVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQVisualDataOutput"); + iqActiveDemodVisualQueue = (DemodulatorThreadInputQueue*)getOutputQueue("IQActiveDemodVisualDataOutput"); iqDataInQueue->set_max_num_items(0); + + std::vector dcBuf; while (!terminated) { SDRThreadIQData *data_in; @@ -178,24 +180,25 @@ void SDRPostThread::run() { // } // } - if (iqVisualQueue != NULL || iqDataOutQueue != NULL) { - bool doIQVis = iqVisualQueue && !iqVisualQueue->full(); - bool doIQOut = iqDataOutQueue != NULL; - + if (iqDataOutQueue != NULL && !iqDataOutQueue->full()) { DemodulatorThreadIQData *iqDataOut = visualDataBuffers.getBuffer(); - iqDataOut->setRefCount((doIQVis?1:0) + (doIQOut?1:0)); + + bool doVis = false; + + if (iqVisualQueue != NULL && !iqVisualQueue->full()) { + doVis = true; + } + + iqDataOut->setRefCount(1 + (doVis?1:0)); iqDataOut->frequency = data_in->frequency; iqDataOut->sampleRate = data_in->sampleRate; iqDataOut->data.assign(data_in->data.begin(), data_in->data.begin() + dataSize); - if (doIQVis) { + iqDataOutQueue->push(iqDataOut); + if (doVis) { iqVisualQueue->push(iqDataOut); } - - if (doIQOut) { - iqDataOutQueue->push(iqDataOut); - } } busy_demod.lock(); @@ -211,6 +214,8 @@ void SDRPostThread::run() { doRefresh.store(false); } + DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); + int activeDemodChannel = -1; // Find active demodulators if (nRunDemods) { @@ -220,7 +225,7 @@ void SDRPostThread::run() { // } // channelize data - // firpfbch2 output rate is 2 x ( input rate / channels ) + // firpfbch output rate is (input rate / channels) for (int i = 0, iMax = dataSize; i < iMax; i+=numChannels) { firpfbch_crcf_analyzer_execute(channelizer, &data_in->data[i], &dataOut[i]); } @@ -239,30 +244,29 @@ void SDRPostThread::run() { if (fdelta < minDelta) { minDelta = fdelta; demodChannel[i] = j; + if (demod == activeDemod) { + activeDemodChannel = j; + } } } } - + for (int i = 0; i < nRunDemods; i++) { // cache channel usage refcounts if (demodChannel[i] >= 0) { demodChannelActive[demodChannel[i]]++; } } - // Run channels for (int i = 0; i < numChannels; i++) { - if (demodChannelActive[i] == 0) { - // Nothing using this channel, skip - continue; - } - + bool doVis = (activeDemodChannel == i) && (iqActiveDemodVisualQueue != NULL) && !iqActiveDemodVisualQueue->full(); + DemodulatorThreadIQData *demodDataOut = buffers.getBuffer(); - demodDataOut->setRefCount(demodChannelActive[i]); + demodDataOut->setRefCount(demodChannelActive[i] + (doVis?1:0)); demodDataOut->frequency = chanCenters[i]; demodDataOut->sampleRate = chanBw; - + // Calculate channel buffer size int chanDataSize = (outSize/numChannels); @@ -274,9 +278,24 @@ void SDRPostThread::run() { } // prepare channel data buffer - for (int j = 0, idx = i; j < chanDataSize; j++) { - idx += numChannels; - demodDataOut->data[j] = dataOut[idx]; + if (i == 0) { // Channel 0 requires DC correction + if (dcBuf.size() != chanDataSize) { + dcBuf.resize(chanDataSize); + } + for (int j = 0, idx = i; j < chanDataSize; j++) { + idx += numChannels; + dcBuf[j] = dataOut[idx]; + } + iirfilt_crcf_execute_block(dcFilter, &dcBuf[0], chanDataSize, &demodDataOut->data[0]); + } else { + for (int j = 0, idx = i; j < chanDataSize; j++) { + idx += numChannels; + demodDataOut->data[j] = dataOut[idx]; + } + } + + if (doVis) { + iqActiveDemodVisualQueue->push(demodDataOut); } for (int j = 0; j < nRunDemods; j++) { diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 86eeec3..b3a2d4c 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -25,7 +25,8 @@ protected: SDRThreadIQDataQueue *iqDataInQueue; DemodulatorThreadInputQueue *iqDataOutQueue; DemodulatorThreadInputQueue *iqVisualQueue; - + DemodulatorThreadInputQueue *iqActiveDemodVisualQueue; + std::mutex busy_demod; std::vector demodulators; std::atomic_bool swapIQ; @@ -51,4 +52,5 @@ private: int numChannels, sampleRate; long long frequency; firpfbch_crcf channelizer; + iirfilt_crcf dcFilter; }; diff --git a/src/sdr/SoapySDRThread.cpp b/src/sdr/SoapySDRThread.cpp index f43030a..8fe7995 100644 --- a/src/sdr/SoapySDRThread.cpp +++ b/src/sdr/SoapySDRThread.cpp @@ -30,7 +30,7 @@ SDRThread::SDRThread() : IOThread() { hasHardwareDC.store(false); numChannels.store(8); - dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); +// dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); } SDRThread::~SDRThread() { @@ -80,7 +80,7 @@ void SDRThread::init() { } if (chan->hasHardwareDC()) { hasHardwareDC.store(true); - wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found hardware DC offset correction support, internal disabled.")); +// wxGetApp().sdrEnumThreadNotify(SDREnumerator::SDR_ENUM_MESSAGE, std::string("Found hardware DC offset correction support, internal disabled.")); device->setDCOffsetMode(SOAPY_SDR_RX, chan->getChannel(), true); } else { hasHardwareDC.store(false); @@ -121,14 +121,14 @@ void SDRThread::readStream(SDRThreadIQDataQueue* iqDataOutQueue) { if (n_read > 0 && !terminated) { SDRThreadIQData *dataOut = buffers.getBuffer(); - if (hasHardwareDC) { +// if (hasHardwareDC) { dataOut->data.assign(inpBuffer.data.begin(), inpBuffer.data.begin()+n_read); - } else { - if (dataOut->data.size() != n_read) { - dataOut->data.resize(n_read); - } - iirfilt_crcf_execute_block(dcFilter, &inpBuffer.data[0], n_read, &dataOut->data[0]); - } +// } else { +// if (dataOut->data.size() != n_read) { +// dataOut->data.resize(n_read); +// } +// iirfilt_crcf_execute_block(dcFilter, &inpBuffer.data[0], n_read, &dataOut->data[0]); +// } dataOut->setRefCount(1); diff --git a/src/sdr/SoapySDRThread.h b/src/sdr/SoapySDRThread.h index b64a684..d86044f 100644 --- a/src/sdr/SoapySDRThread.h +++ b/src/sdr/SoapySDRThread.h @@ -77,7 +77,6 @@ protected: SoapySDR::Device *device; void *buffs[1]; ReBuffer buffers; - iirfilt_crcf dcFilter; SDRThreadIQData inpBuffer; std::atomic deviceConfig; std::atomic deviceInfo;