diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index d6ae6fc..2816b24 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -855,6 +855,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) { wproc->setView(waterfallCanvas->getViewState()); wproc->setBandwidth(waterfallCanvas->getBandwidth()); wproc->setCenterFrequency(waterfallCanvas->getCenterFrequency()); + wxGetApp().getSDRPostThread()->setIQVisualRange(waterfallCanvas->getCenterFrequency(), waterfallCanvas->getBandwidth()); // waterfallCanvas->processInputQueue(); // waterfallCanvas->Refresh(); diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 141e02b..791b1ba 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -377,6 +377,10 @@ DemodulatorMgr &CubicSDR::getDemodMgr() { return demodMgr; } +SDRPostThread *CubicSDR::getSDRPostThread() { + return sdrPostThread; +} + void CubicSDR::bindDemodulator(DemodulatorInstance *demod) { if (!demod) { return; diff --git a/src/CubicSDR.h b/src/CubicSDR.h index f7d7b9a..acfb800 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -77,6 +77,8 @@ public: DemodulatorThreadInputQueue* getActiveDemodVisualQueue(); DemodulatorMgr &getDemodMgr(); + SDRPostThread *getSDRPostThread(); + void bindDemodulator(DemodulatorInstance *demod); void removeDemodulator(DemodulatorInstance *demod); diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index e1274e2..133beb4 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -59,7 +59,7 @@ void DemodulatorThread::run() { nco_crcf_pll_set_bandwidth(stereoPilot, 0.25f); // half band filter used for side-band elimination - resamp2_cccf ssbFilt = resamp2_cccf_create(12,-0.25f,60.0f); + resamp2_crcf ssbFilt = resamp2_crcf_create(12,-0.25f,60.0f); // Automatic IQ gain iqAutoGain = agc_crcf_create(); @@ -192,13 +192,13 @@ void DemodulatorThread::run() { switch (demodulatorType.load()) { case DEMOD_TYPE_LSB: for (int i = 0; i < bufSize; i++) { // Reject upper band - resamp2_cccf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); + resamp2_crcf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); ampmodem_demodulate(demodAM, x, &demodOutputData[i]); } break; case DEMOD_TYPE_USB: for (int i = 0; i < bufSize; i++) { // Reject lower band - resamp2_cccf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); + resamp2_crcf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); ampmodem_demodulate(demodAM, y, &demodOutputData[i]); } break; @@ -487,7 +487,7 @@ void DemodulatorThread::run() { firhilbf_destroy(firStereoR2C); firhilbf_destroy(firStereoC2R); nco_crcf_destroy(stereoPilot); - resamp2_cccf_destroy(ssbFilt); + resamp2_crcf_destroy(ssbFilt); outputBuffers.purge(); diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 3710ef7..31ec0b7 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -17,6 +17,9 @@ SDRPostThread::SDRPostThread() : IOThread() { sampleRate = 0; nRunDemods = 0; + visFrequency.store(0); + visBandwidth.store(0); + doRefresh.store(false); dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); } @@ -128,6 +131,24 @@ void SDRPostThread::updateChannels() { chanCenters[numChannels] = frequency + (sampleRate/2); } +int SDRPostThread::getChannelAt(long long frequency) { + int chan = -1; + long long minDelta = sampleRate; + for (int i = 0; i < numChannels+1; i++) { + long long fdelta = abs(frequency - chanCenters[i]); + if (fdelta < minDelta) { + minDelta = fdelta; + chan = i; + } + } + return chan; +} + +void SDRPostThread::setIQVisualRange(long long frequency, int bandwidth) { + visFrequency.store(frequency); + visBandwidth.store(bandwidth); +} + void SDRPostThread::run() { #ifdef __APPLE__ pthread_t tID = pthread_self(); // ID of this thread @@ -181,7 +202,13 @@ void SDRPostThread::run() { // } // } - if (iqDataOutQueue != NULL && !iqDataOutQueue->full()) { + int activeVisChannel = -1; + +// if (visBandwidth.load() && visBandwidth.load() < (chanBw/2)) { +// activeVisChannel = getChannelAt(visFrequency); +// } + + if (iqDataOutQueue != NULL && !iqDataOutQueue->full() && activeVisChannel < 0) { DemodulatorThreadIQData *iqDataOut = visualDataBuffers.getBuffer(); bool doVis = false; @@ -219,7 +246,7 @@ void SDRPostThread::run() { int activeDemodChannel = -1; // Find active demodulators - if (nRunDemods) { + if (nRunDemods || (activeVisChannel >= 0)) { // for (int i = 0; i < numChannels; i++) { // firpfbch_crcf_set_channel_state(channelizer, i, (demodChannelActive[i]>0)?1:0); @@ -238,17 +265,9 @@ void SDRPostThread::run() { // Find nearest channel for each demodulator for (int i = 0; i < nRunDemods; i++) { DemodulatorInstance *demod = runDemods[i]; - long long minDelta = data_in->sampleRate; - for (int j = 0, jMax = numChannels+1; j < jMax; j++) { - // Distance from channel center to demod center - long long fdelta = abs(demod->getFrequency() - chanCenters[j]); - if (fdelta < minDelta) { - minDelta = fdelta; - demodChannel[i] = j; - if (demod == activeDemod) { - activeDemodChannel = j; - } - } + demodChannel[i] = getChannelAt(demod->getFrequency()); + if (demod == activeDemod) { + activeDemodChannel = demodChannel[i]; } } @@ -261,10 +280,19 @@ void SDRPostThread::run() { // Run channels for (int i = 0; i < numChannels+1; i++) { - bool doVis = (activeDemodChannel == i) && (iqActiveDemodVisualQueue != NULL) && !iqActiveDemodVisualQueue->full(); + int doDemodVis = ((activeDemodChannel == i) && (iqActiveDemodVisualQueue != NULL) && !iqActiveDemodVisualQueue->full())?1:0; + int doVis = 0; + +// if (activeVisChannel == i) { +// doVis = (((iqDataOutQueue != NULL))?1:0) + ((iqVisualQueue != NULL && !iqVisualQueue->full())?1:0); +// } + + if (!doVis && !doDemodVis && demodChannelActive[i] == 0) { + continue; + } DemodulatorThreadIQData *demodDataOut = buffers.getBuffer(); - demodDataOut->setRefCount(demodChannelActive[i] + (doVis?1:0)); + demodDataOut->setRefCount(demodChannelActive[i] + doVis + doDemodVis); demodDataOut->frequency = chanCenters[i]; demodDataOut->sampleRate = chanBw; @@ -303,7 +331,14 @@ void SDRPostThread::run() { } } - if (doVis) { +// if (doVis) { +// iqDataOutQueue->push(demodDataOut); +// if (doVis>1) { +// iqVisualQueue->push(demodDataOut); +// } +// } + + if (doDemodVis) { iqActiveDemodVisualQueue->push(demodDataOut); } diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index b3a2d4c..7a9b634 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -21,6 +21,8 @@ public: void run(); void terminate(); + void setIQVisualRange(long long frequency, int bandwidth); + protected: SDRThreadIQDataQueue *iqDataInQueue; DemodulatorThreadInputQueue *iqDataOutQueue; @@ -35,6 +37,7 @@ private: void initPFBChannelizer(); void updateActiveDemodulators(); void updateChannels(); + int getChannelAt(long long frequency); ReBuffer buffers; std::vector fpData; @@ -49,6 +52,8 @@ private: ReBuffer visualDataBuffers; atomic_bool doRefresh; + atomic_llong visFrequency; + atomic_int visBandwidth; int numChannels, sampleRate; long long frequency; firpfbch_crcf channelizer;