diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 7da51f7..301c732 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -32,6 +32,8 @@ IMPLEMENT_APP(CubicSDR) #include "ActionDialog.h" +#include + //#ifdef ENABLE_DIGITAL_LAB //// console output buffer for windows @@ -290,17 +292,17 @@ bool CubicSDR::OnInit() { // Visual Data spectrumVisualThread = new SpectrumVisualDataThread(); - pipeIQVisualData = new DemodulatorThreadInputQueue(); + pipeIQVisualData = std::make_shared(); pipeIQVisualData->set_max_num_items(1); - pipeWaterfallIQVisualData = new DemodulatorThreadInputQueue(); + pipeWaterfallIQVisualData = std::make_shared(); pipeWaterfallIQVisualData->set_max_num_items(128); getSpectrumProcessor()->setInput(pipeIQVisualData); getSpectrumProcessor()->setHideDC(true); // I/Q Data - pipeSDRIQData = new SDRThreadIQDataQueue(); + pipeSDRIQData = std::make_shared(); pipeSDRIQData->set_max_num_items(100); sdrThread = new SDRThread(); @@ -313,7 +315,7 @@ bool CubicSDR::OnInit() { sdrPostThread->setOutputQueue("IQDataOutput", pipeWaterfallIQVisualData); #if CUBICSDR_ENABLE_VIEW_SCOPE - pipeAudioVisualData = new DemodulatorThreadOutputQueue(); + pipeAudioVisualData = std::make_shared(); pipeAudioVisualData->set_max_num_items(1); scopeProcessor.setInput(pipeAudioVisualData); @@ -323,7 +325,7 @@ bool CubicSDR::OnInit() { #if CUBICSDR_ENABLE_VIEW_DEMOD demodVisualThread = new SpectrumVisualDataThread(); - pipeDemodIQVisualData = new DemodulatorThreadInputQueue(); + pipeDemodIQVisualData = std::make_shared(); pipeDemodIQVisualData->set_max_num_items(1); if (getDemodSpectrumProcessor()) { @@ -478,15 +480,6 @@ int CubicSDR::OnExit() { delete demodVisualThread; demodVisualThread = nullptr; - - delete pipeIQVisualData; - pipeIQVisualData = nullptr; - - delete pipeAudioVisualData; - pipeAudioVisualData = nullptr; - - delete pipeSDRIQData; - pipeSDRIQData = nullptr; delete m_glContext; m_glContext = nullptr; @@ -795,15 +788,15 @@ SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcessor() { } } -DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { +DemodulatorThreadOutputQueuePtr CubicSDR::getAudioVisualQueue() { return pipeAudioVisualData; } -DemodulatorThreadInputQueue* CubicSDR::getIQVisualQueue() { +DemodulatorThreadInputQueuePtr CubicSDR::getIQVisualQueue() { return pipeIQVisualData; } -DemodulatorThreadInputQueue* CubicSDR::getWaterfallVisualQueue() { +DemodulatorThreadInputQueuePtr CubicSDR::getWaterfallVisualQueue() { return pipeWaterfallIQVisualData; } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 3dbbbc4..c688c53 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -107,10 +107,10 @@ public: SpectrumVisualProcessor *getSpectrumProcessor(); SpectrumVisualProcessor *getDemodSpectrumProcessor(); - DemodulatorThreadOutputQueue* getAudioVisualQueue(); - DemodulatorThreadInputQueue* getIQVisualQueue(); - DemodulatorThreadInputQueue* getWaterfallVisualQueue(); - DemodulatorThreadInputQueue* getActiveDemodVisualQueue(); + DemodulatorThreadOutputQueuePtr getAudioVisualQueue(); + DemodulatorThreadInputQueuePtr getIQVisualQueue(); + DemodulatorThreadInputQueuePtr getWaterfallVisualQueue(); + DemodulatorThreadInputQueuePtr getActiveDemodVisualQueue(); DemodulatorMgr &getDemodMgr(); BookmarkMgr &getBookmarkMgr(); @@ -197,12 +197,12 @@ private: SpectrumVisualDataThread *spectrumVisualThread = nullptr; SpectrumVisualDataThread *demodVisualThread = nullptr; - SDRThreadIQDataQueue* pipeSDRIQData = nullptr; - DemodulatorThreadInputQueue* pipeIQVisualData = nullptr; - DemodulatorThreadOutputQueue* pipeAudioVisualData = nullptr; - DemodulatorThreadInputQueue* pipeDemodIQVisualData = nullptr; - DemodulatorThreadInputQueue* pipeWaterfallIQVisualData = nullptr; - DemodulatorThreadInputQueue* pipeActiveDemodIQVisualData = nullptr; + SDRThreadIQDataQueuePtr pipeSDRIQData = nullptr; + DemodulatorThreadInputQueuePtr pipeIQVisualData = nullptr; + DemodulatorThreadOutputQueuePtr pipeAudioVisualData = nullptr; + DemodulatorThreadInputQueuePtr pipeDemodIQVisualData = nullptr; + DemodulatorThreadInputQueuePtr pipeWaterfallIQVisualData = nullptr; + DemodulatorThreadInputQueuePtr pipeActiveDemodIQVisualData = nullptr; ScopeVisualProcessor scopeProcessor; diff --git a/src/IOThread.cpp b/src/IOThread.cpp index 074af53..5d78b64 100644 --- a/src/IOThread.cpp +++ b/src/IOThread.cpp @@ -3,6 +3,7 @@ #include "IOThread.h" #include +#include #define SPIN_WAIT_SLEEP_MS 5 @@ -68,32 +69,32 @@ void IOThread::terminate() { stopping.store(true); }; -void IOThread::onBindOutput(std::string /* name */, ThreadQueueBase* /* threadQueue */) { +void IOThread::onBindOutput(std::string /* name */, ThreadQueueBasePtr /* threadQueue */) { }; -void IOThread::onBindInput(std::string /* name */, ThreadQueueBase* /* threadQueue */) { +void IOThread::onBindInput(std::string /* name */, ThreadQueueBasePtr /* threadQueue */) { }; -void IOThread::setInputQueue(std::string qname, ThreadQueueBase *threadQueue) { +void IOThread::setInputQueue(std::string qname, ThreadQueueBasePtr threadQueue) { std::lock_guard < std::mutex > lock(m_queue_bindings_mutex); input_queues[qname] = threadQueue; this->onBindInput(qname, threadQueue); }; -ThreadQueueBase *IOThread::getInputQueue(std::string qname) { +ThreadQueueBasePtr IOThread::getInputQueue(std::string qname) { std::lock_guard < std::mutex > lock(m_queue_bindings_mutex); return input_queues[qname]; }; -void IOThread::setOutputQueue(std::string qname, ThreadQueueBase *threadQueue) { +void IOThread::setOutputQueue(std::string qname, ThreadQueueBasePtr threadQueue) { std::lock_guard < std::mutex > lock(m_queue_bindings_mutex); output_queues[qname] = threadQueue; this->onBindOutput(qname, threadQueue); }; -ThreadQueueBase *IOThread::getOutputQueue(std::string qname) { +ThreadQueueBasePtr IOThread::getOutputQueue(std::string qname) { std::lock_guard < std::mutex > lock(m_queue_bindings_mutex); return output_queues[qname]; }; diff --git a/src/IOThread.h b/src/IOThread.h index c8fe54c..d35765f 100644 --- a/src/IOThread.h +++ b/src/IOThread.h @@ -175,17 +175,17 @@ public: //If wait < 0, the wait in infinite until the thread dies. bool isTerminated(int waitMs = 0); - virtual void onBindOutput(std::string name, ThreadQueueBase* threadQueue); - virtual void onBindInput(std::string name, ThreadQueueBase* threadQueue); + virtual void onBindOutput(std::string name, ThreadQueueBasePtr threadQueue); + virtual void onBindInput(std::string name, ThreadQueueBasePtr threadQueue); - void setInputQueue(std::string qname, ThreadQueueBase *threadQueue); - ThreadQueueBase *getInputQueue(std::string qname); - void setOutputQueue(std::string qname, ThreadQueueBase *threadQueue); - ThreadQueueBase *getOutputQueue(std::string qname); + void setInputQueue(std::string qname, ThreadQueueBasePtr threadQueue); + ThreadQueueBasePtr getInputQueue(std::string qname); + void setOutputQueue(std::string qname, ThreadQueueBasePtr threadQueue); + ThreadQueueBasePtr getOutputQueue(std::string qname); protected: - std::map input_queues; - std::map output_queues; + std::map input_queues; + std::map output_queues; //this protects against concurrent changes in input/output bindings: get/set/Input/OutPutQueue std::mutex m_queue_bindings_mutex; diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index a96cf34..9498242 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -73,7 +73,7 @@ static int audioCallback(void *outputBuffer, void * /* inputBuffer */, unsigned //Zero output buffer in all cases: this allow to mute audio if no AudioThread data is //actually active. - memset(out, 0, nBufferFrames * 2 * sizeof(float)); + ::memset(out, 0, nBufferFrames * 2 * sizeof(float)); AudioThread *src = (AudioThread *) userData; @@ -424,8 +424,8 @@ void AudioThread::run() { setupDevice((outputDevice.load() == -1) ? (dac.getDefaultOutputDevice()) : outputDevice.load()); // std::cout << "Audio thread started." << std::endl; - - inputQueue = static_cast(getInputQueue("AudioDataInput")); + + inputQueue = std::static_pointer_cast(getInputQueue("AudioDataInput")); //Infinite loop, witing for commands or for termination while (!stopping) { @@ -451,7 +451,7 @@ void AudioThread::run() { if (inputQueue != nullptr) { inputQueue->flush(); } - + //Nullify currentInput... currentInput = nullptr; @@ -499,7 +499,6 @@ void AudioThread::setActive(bool state) { // Activity state changing, clear any inputs if(inputQueue) { - inputQueue->flush(); } active = state; diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 7d53fb1..fd811f1 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -52,10 +52,13 @@ public: typedef ThreadBlockingQueue AudioThreadInputQueue; typedef ThreadBlockingQueue AudioThreadCommandQueue; +typedef std::shared_ptr AudioThreadInputQueuePtr; +typedef std::shared_ptr AudioThreadCommandQueuePtr; + class AudioThread : public IOThread { public: AudioThreadInputPtr currentInput; - AudioThreadInputQueue *inputQueue; + AudioThreadInputQueuePtr inputQueue; std::atomic_uint audioQueuePtr; std::atomic_uint underflowCount; std::atomic_bool initialized; diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index ae6c239..6d22495 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -103,6 +103,10 @@ public: typedef std::shared_ptr DemodulatorThreadIQDataPtr; typedef std::shared_ptr DemodulatorThreadPostIQDataPtr; -typedef ThreadBlockingQueue< DemodulatorThreadIQDataPtr > DemodulatorThreadInputQueue; -typedef ThreadBlockingQueue< DemodulatorThreadPostIQDataPtr > DemodulatorThreadPostInputQueue; +typedef ThreadBlockingQueue DemodulatorThreadInputQueue; +typedef ThreadBlockingQueue DemodulatorThreadPostInputQueue; typedef ThreadBlockingQueue DemodulatorThreadControlCommandQueue; + +typedef std::shared_ptr DemodulatorThreadInputQueuePtr; +typedef std::shared_ptr DemodulatorThreadPostInputQueuePtr; +typedef std::shared_ptr DemodulatorThreadControlCommandQueuePtr; diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index 9605707..bbeded7 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -1,6 +1,7 @@ // Copyright (c) Charles J. Cliffe // SPDX-License-Identifier: GPL-2.0+ +#include #include "DemodulatorInstance.h" #include "CubicSDR.h" @@ -52,9 +53,9 @@ DemodulatorInstance::DemodulatorInstance() { label.store(new std::string("Unnamed")); user_label.store(new std::wstring()); - pipeIQInputData = new DemodulatorThreadInputQueue; + pipeIQInputData = std::make_shared(); pipeIQInputData->set_max_num_items(100); - pipeIQDemodData = new DemodulatorThreadPostInputQueue; + pipeIQDemodData = std::make_shared< DemodulatorThreadPostInputQueue>(); pipeIQInputData->set_max_num_items(100); audioThread = new AudioThread(); @@ -63,10 +64,10 @@ DemodulatorInstance::DemodulatorInstance() { demodulatorPreThread->setInputQueue("IQDataInput",pipeIQInputData); demodulatorPreThread->setOutputQueue("IQDataOutput",pipeIQDemodData); - pipeAudioData = new AudioThreadInputQueue; + pipeAudioData = std::make_shared< AudioThreadInputQueue>(); pipeAudioData->set_max_num_items(10); - threadQueueControl = new DemodulatorThreadControlCommandQueue; + threadQueueControl = std::make_shared< DemodulatorThreadControlCommandQueue>(); threadQueueControl->set_max_num_items(2); demodulatorThread = new DemodulatorThread(this); @@ -85,15 +86,9 @@ DemodulatorInstance::~DemodulatorInstance() { delete audioThread; delete demodulatorThread; delete demodulatorPreThread; - delete pipeIQInputData; - delete pipeIQDemodData; - delete threadQueueControl; - delete pipeAudioData; - - // wxGetApp().getBookmarkMgr().updateActiveList(); } -void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { +void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueuePtr tQueue) { demodulatorThread->setOutputQueue("AudioVisualOutput", tQueue); } @@ -131,8 +126,6 @@ void DemodulatorInstance::run() { #endif active = true; - - // wxGetApp().getBookmarkMgr().updateActiveList(); } void DemodulatorInstance::updateLabel(long long freq) { @@ -492,7 +485,7 @@ DemodVisualCue *DemodulatorInstance::getVisualCue() { return &visualCue; } -DemodulatorThreadInputQueue *DemodulatorInstance::getIQInputDataPipe() { +DemodulatorThreadInputQueuePtr DemodulatorInstance::getIQInputDataPipe() { return pipeIQInputData; } diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index bb4fd52..ac1aa64 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -48,7 +48,7 @@ public: DemodulatorInstance(); ~DemodulatorInstance(); - void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue); + void setVisualOutputQueue(DemodulatorThreadOutputQueuePtr tQueue); void run(); void terminate(); @@ -111,7 +111,7 @@ public: DemodVisualCue *getVisualCue(); - DemodulatorThreadInputQueue *getIQInputDataPipe(); + DemodulatorThreadInputQueuePtr getIQInputDataPipe(); ModemArgInfoList getModemArgs(); std::string readModemSetting(std::string setting); @@ -131,12 +131,12 @@ public: #endif private: - DemodulatorThreadInputQueue* pipeIQInputData; - DemodulatorThreadPostInputQueue* pipeIQDemodData; - AudioThreadInputQueue *pipeAudioData; + DemodulatorThreadInputQueuePtr pipeIQInputData; + DemodulatorThreadPostInputQueuePtr pipeIQDemodData; + AudioThreadInputQueuePtr pipeAudioData; DemodulatorPreThread *demodulatorPreThread; DemodulatorThread *demodulatorThread; - DemodulatorThreadControlCommandQueue *threadQueueControl; + DemodulatorThreadControlCommandQueuePtr threadQueueControl; //protects child thread creation and termination std::mutex m_thread_control_mutex; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index a2f472d..f34f78c 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -23,10 +23,10 @@ DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance *parent) : IOThre freqShifter = nco_crcf_create(LIQUID_VCO); shiftFrequency = 0; - workerQueue = new DemodulatorThreadWorkerCommandQueue; + workerQueue = std::make_shared(); workerQueue->set_max_num_items(2); - workerResults = new DemodulatorThreadWorkerResultQueue; + workerResults = std::make_shared(); workerResults->set_max_num_items(100); workerThread = new DemodulatorWorkerThread(); @@ -65,8 +65,8 @@ void DemodulatorPreThread::run() { ReBuffer buffers("DemodulatorPreThreadBuffers"); - iqInputQueue = static_cast(getInputQueue("IQDataInput")); - iqOutputQueue = static_cast(getOutputQueue("IQDataOutput")); + iqInputQueue = std::static_pointer_cast(getInputQueue("IQDataInput")); + iqOutputQueue = std::static_pointer_cast(getOutputQueue("IQDataOutput")); std::vector in_buf_data; std::vector out_buf_data; @@ -359,7 +359,7 @@ void DemodulatorPreThread::terminate() { DemodulatorWorkerThreadCommand command; //VSO: blocking push : workerQueue->push(command); - + //wait blocking for termination here, it could be long with lots of modems and we MUST terminate properly, //else better kill the whole application... workerThread->isTerminated(5000); @@ -370,12 +370,6 @@ void DemodulatorPreThread::terminate() { delete workerThread; workerThread = nullptr; - - delete workerResults; - workerResults = nullptr; - - delete workerQueue; - workerQueue = nullptr; } Modem *DemodulatorPreThread::getModem() { diff --git a/src/demod/DemodulatorPreThread.h b/src/demod/DemodulatorPreThread.h index 88e6dff..67523d4 100644 --- a/src/demod/DemodulatorPreThread.h +++ b/src/demod/DemodulatorPreThread.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "CubicSDRDefs.h" #include "DemodDefs.h" @@ -78,9 +79,9 @@ protected: DemodulatorWorkerThread *workerThread; std::thread *t_Worker; - DemodulatorThreadWorkerCommandQueue *workerQueue; - DemodulatorThreadWorkerResultQueue *workerResults; + DemodulatorThreadWorkerCommandQueuePtr workerQueue; + DemodulatorThreadWorkerResultQueuePtr workerResults; - DemodulatorThreadInputQueue* iqInputQueue; - DemodulatorThreadPostInputQueue* iqOutputQueue; + DemodulatorThreadInputQueuePtr iqInputQueue; + DemodulatorThreadPostInputQueuePtr iqOutputQueue; }; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 20b7637..f4e84f2 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -35,13 +35,13 @@ DemodulatorThread::~DemodulatorThread() { releaseSquelchLock(demodInstance); } -void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBase *threadQueue) { +void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBasePtr threadQueue) { if (name == "AudioVisualOutput") { //protects because it may be changed at runtime std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue); - audioVisOutputQueue = static_cast(threadQueue); + audioVisOutputQueue = std::static_pointer_cast(threadQueue); } } @@ -75,9 +75,9 @@ void DemodulatorThread::run() { // std::cout << "Demodulator thread started.." << std::endl; - iqInputQueue = static_cast(getInputQueue("IQDataInput")); - audioOutputQueue = static_cast(getOutputQueue("AudioDataOutput")); - threadQueueControl = static_cast(getInputQueue("ControlQueue")); + iqInputQueue = std::static_pointer_cast(getInputQueue("IQDataInput")); + audioOutputQueue = std::static_pointer_cast(getOutputQueue("AudioDataOutput")); + threadQueueControl = std::static_pointer_cast(getInputQueue("ControlQueue")); ModemIQData modemData; @@ -234,7 +234,7 @@ void DemodulatorThread::run() { //At that point, capture the current state of audioVisOutputQueue in a local //variable, and works with it with now on until the next while-turn. - DemodulatorThreadOutputQueue* localAudioVisOutputQueue = nullptr; + DemodulatorThreadOutputQueuePtr localAudioVisOutputQueue = nullptr; { std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue); localAudioVisOutputQueue = audioVisOutputQueue; diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index d9c9a5a..3970601 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -5,6 +5,7 @@ #include #include +#include #include "DemodDefs.h" #include "AudioThread.h" @@ -12,6 +13,8 @@ typedef ThreadBlockingQueue DemodulatorThreadOutputQueue; +typedef std::shared_ptr DemodulatorThreadOutputQueuePtr; + #define DEMOD_VIS_SIZE 2048 #define DEMOD_SIGNAL_MIN -30 #define DEMOD_SIGNAL_MAX 30 @@ -24,7 +27,7 @@ public: DemodulatorThread(DemodulatorInstance *parent); virtual ~DemodulatorThread(); - void onBindOutput(std::string name, ThreadQueueBase *threadQueue); + void onBindOutput(std::string name, ThreadQueueBasePtr threadQueue); void run(); void terminate(); @@ -62,10 +65,10 @@ protected: Modem *cModem = nullptr; ModemKit *cModemKit = nullptr; - DemodulatorThreadPostInputQueue* iqInputQueue = nullptr; - AudioThreadInputQueue *audioOutputQueue = nullptr; - DemodulatorThreadOutputQueue* audioVisOutputQueue = nullptr; - DemodulatorThreadControlCommandQueue *threadQueueControl = nullptr; + DemodulatorThreadPostInputQueuePtr iqInputQueue = nullptr; + AudioThreadInputQueuePtr audioOutputQueue = nullptr; + DemodulatorThreadOutputQueuePtr audioVisOutputQueue = nullptr; + DemodulatorThreadControlCommandQueuePtr threadQueueControl = nullptr; //protects the audioVisOutputQueue dynamic binding change at runtime (in DemodulatorMgr) std::mutex m_mutexAudioVisOutputQueue; diff --git a/src/demod/DemodulatorWorkerThread.cpp b/src/demod/DemodulatorWorkerThread.cpp index e2eec84..863065f 100644 --- a/src/demod/DemodulatorWorkerThread.cpp +++ b/src/demod/DemodulatorWorkerThread.cpp @@ -10,7 +10,7 @@ #define HEARTBEAT_CHECK_PERIOD_MICROS (50 * 1000) DemodulatorWorkerThread::DemodulatorWorkerThread() : IOThread(), - commandQueue(NULL), resultQueue(NULL), cModem(nullptr), cModemKit(nullptr) { + commandQueue(nullptr), resultQueue(nullptr), cModem(nullptr), cModemKit(nullptr) { } DemodulatorWorkerThread::~DemodulatorWorkerThread() { @@ -20,8 +20,8 @@ void DemodulatorWorkerThread::run() { // std::cout << "Demodulator worker thread started.." << std::endl; - commandQueue = static_cast(getInputQueue("WorkerCommandQueue")); - resultQueue = static_cast(getOutputQueue("WorkerResultQueue")); + commandQueue = std::static_pointer_cast(getInputQueue("WorkerCommandQueue")); + resultQueue = std::static_pointer_cast(getOutputQueue("WorkerResultQueue")); while (!stopping) { bool filterChanged = false; diff --git a/src/demod/DemodulatorWorkerThread.h b/src/demod/DemodulatorWorkerThread.h index 0ebff7c..54b2899 100644 --- a/src/demod/DemodulatorWorkerThread.h +++ b/src/demod/DemodulatorWorkerThread.h @@ -5,7 +5,7 @@ #include #include - +#include #include "liquid/liquid.h" #include "AudioThread.h" #include "ThreadBlockingQueue.h" @@ -72,6 +72,9 @@ public: typedef ThreadBlockingQueue DemodulatorThreadWorkerCommandQueue; typedef ThreadBlockingQueue DemodulatorThreadWorkerResultQueue; +typedef std::shared_ptr DemodulatorThreadWorkerCommandQueuePtr; +typedef std::shared_ptr DemodulatorThreadWorkerResultQueuePtr; + class DemodulatorWorkerThread : public IOThread { public: @@ -80,11 +83,11 @@ public: virtual void run(); - void setCommandQueue(DemodulatorThreadWorkerCommandQueue *tQueue) { + void setCommandQueue(DemodulatorThreadWorkerCommandQueuePtr tQueue) { commandQueue = tQueue; } - void setResultQueue(DemodulatorThreadWorkerResultQueue *tQueue) { + void setResultQueue(DemodulatorThreadWorkerResultQueuePtr tQueue) { resultQueue = tQueue; } @@ -92,8 +95,8 @@ public: protected: - DemodulatorThreadWorkerCommandQueue *commandQueue; - DemodulatorThreadWorkerResultQueue *resultQueue; + DemodulatorThreadWorkerCommandQueuePtr commandQueue; + DemodulatorThreadWorkerResultQueuePtr resultQueue; Modem *cModem; ModemKit *cModemKit; std::string cModemType; diff --git a/src/process/FFTVisualDataThread.cpp b/src/process/FFTVisualDataThread.cpp index cfd8c08..8a3d2e3 100644 --- a/src/process/FFTVisualDataThread.cpp +++ b/src/process/FFTVisualDataThread.cpp @@ -27,11 +27,12 @@ SpectrumVisualProcessor *FFTVisualDataThread::getProcessor() { } void FFTVisualDataThread::run() { - DemodulatorThreadInputQueue *pipeIQDataIn = static_cast(getInputQueue("IQDataInput")); - SpectrumVisualDataQueue *pipeFFTDataOut = static_cast(getOutputQueue("FFTDataOutput")); + + DemodulatorThreadInputQueuePtr pipeIQDataIn = std::static_pointer_cast(getInputQueue("IQDataInput")); + SpectrumVisualDataQueuePtr pipeFFTDataOut = std::static_pointer_cast(getOutputQueue("FFTDataOutput")); - fftQueue.set_max_num_items(100); + fftQueue->set_max_num_items(100); pipeFFTDataOut->set_max_num_items(100); //FFT distributor plumbing: @@ -39,10 +40,10 @@ void FFTVisualDataThread::run() { fftDistrib.setInput(pipeIQDataIn); //The FFT distributor has actually 1 output only, so it doesn't distribute at all :) - fftDistrib.attachOutput(&fftQueue); + fftDistrib.attachOutput(fftQueue); //FFT Distributor output is ==> SpectrumVisualProcessor input. - wproc.setInput(&fftQueue); + wproc.setInput(fftQueue); wproc.attachOutput(pipeFFTDataOut); wproc.setup(DEFAULT_FFT_SIZE); diff --git a/src/process/FFTVisualDataThread.h b/src/process/FFTVisualDataThread.h index 55ff408..70b31a9 100644 --- a/src/process/FFTVisualDataThread.h +++ b/src/process/FFTVisualDataThread.h @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-2.0+ #pragma once - +#include #include "IOThread.h" #include "SpectrumVisualProcessor.h" #include "FFTDataDistributor.h" @@ -20,7 +20,7 @@ public: protected: FFTDataDistributor fftDistrib; - DemodulatorThreadInputQueue fftQueue; + DemodulatorThreadInputQueuePtr fftQueue = std::make_shared(); SpectrumVisualProcessor wproc; std::atomic_int linesPerSecond; diff --git a/src/process/ScopeVisualProcessor.h b/src/process/ScopeVisualProcessor.h index 25185be..0cd5a44 100644 --- a/src/process/ScopeVisualProcessor.h +++ b/src/process/ScopeVisualProcessor.h @@ -28,6 +28,8 @@ typedef std::shared_ptr ScopeRenderDataPtr; typedef ThreadBlockingQueue ScopeRenderDataQueue; +typedef std::shared_ptr ScopeRenderDataQueuePtr; + class ScopeVisualProcessor : public VisualProcessor { public: ScopeVisualProcessor(); diff --git a/src/process/SpectrumVisualProcessor.h b/src/process/SpectrumVisualProcessor.h index 3dcab2f..f147088 100644 --- a/src/process/SpectrumVisualProcessor.h +++ b/src/process/SpectrumVisualProcessor.h @@ -24,6 +24,7 @@ public: typedef std::shared_ptr SpectrumVisualDataPtr; typedef ThreadBlockingQueue SpectrumVisualDataQueue; +typedef std::shared_ptr SpectrumVisualDataQueuePtr; class SpectrumVisualProcessor : public VisualProcessor { public: diff --git a/src/process/VisualProcessor.h b/src/process/VisualProcessor.h index 393c917..13e8966 100644 --- a/src/process/VisualProcessor.h +++ b/src/process/VisualProcessor.h @@ -21,7 +21,10 @@ public: typedef ThreadBlockingQueue VisualInputQueueType; typedef ThreadBlockingQueue VisualOutputQueueType; - typedef typename std::vector< VisualOutputQueueType *>::iterator outputs_i; + typedef std::shared_ptr VisualInputQueueTypePtr; + typedef std::shared_ptr VisualOutputQueueTypePtr; + + typedef typename std::vector< VisualOutputQueueTypePtr >::iterator outputs_i; virtual ~VisualProcessor() { } @@ -35,8 +38,8 @@ public: bool isOutputEmpty() { std::lock_guard < std::recursive_mutex > busy_lock(busy_update); - for (outputs_i it = outputs.begin(); it != outputs.end(); it++) { - if ((*it)->full()) { + for (VisualOutputQueueTypePtr single_output : outputs) { + if (single_output->full()) { return false; } } @@ -46,8 +49,8 @@ public: bool isAnyOutputEmpty() { std::lock_guard < std::recursive_mutex > busy_lock(busy_update); - for (outputs_i it = outputs.begin(); it != outputs.end(); it++) { - if (!(*it)->full()) { + for (VisualOutputQueueTypePtr single_output : outputs) { + if (!(single_output)->full()) { return true; } } @@ -55,7 +58,7 @@ public: } //Set a (new) 'input' queue for incoming data. - void setInput(VisualInputQueueType *vis_in) { + void setInput(VisualInputQueueTypePtr vis_in) { std::lock_guard < std::recursive_mutex > busy_lock(busy_update); input = vis_in; @@ -63,14 +66,14 @@ public: //Add a vis_out queue where to consumed 'input' data will be //dispatched by distribute(). - void attachOutput(VisualOutputQueueType *vis_out) { + void attachOutput(VisualOutputQueueTypePtr vis_out) { // attach an output queue std::lock_guard < std::recursive_mutex > busy_lock(busy_update); outputs.push_back(vis_out); } //reverse of attachOutput(), removed an existing attached vis_out. - void removeOutput(VisualOutputQueueType *vis_out) { + void removeOutput(VisualOutputQueueTypePtr vis_out) { // remove an output queue std::lock_guard < std::recursive_mutex > busy_lock(busy_update); @@ -108,20 +111,20 @@ protected: //We will try to distribute 'output' among all 'outputs', //so 'output' will a-priori be shared among all 'outputs'. - for (outputs_i it = outputs.begin(); it != outputs.end(); it++) { + for (VisualOutputQueueTypePtr single_output : outputs) { //'output' can fail to be given to an outputs_i, //using a blocking push, with a timeout - if (!(*it)->push(item, timeout, errorMessage)) { + if (!(single_output)->push(item, timeout, errorMessage)) { //TODO : trace ? } } } //the incoming data queue - VisualInputQueueType *input = nullptr; + VisualInputQueueTypePtr input = nullptr; //the n-outputs where to process()-ed data is distribute()-ed. - std::vector outputs; + std::vector outputs; //protects input and outputs, must be recursive because of re-entrance std::recursive_mutex busy_update; diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index ad561d0..0a286bf 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -7,6 +7,7 @@ #include #include +#include //50 ms #define HEARTBEAT_CHECK_PERIOD_MICROS (50 * 1000) @@ -179,10 +180,10 @@ void SDRPostThread::run() { // std::cout << "SDR post-processing thread started.." << std::endl; - iqDataInQueue = static_cast(getInputQueue("IQDataInput")); - iqDataOutQueue = static_cast(getOutputQueue("IQDataOutput")); - iqVisualQueue = static_cast(getOutputQueue("IQVisualDataOutput")); - iqActiveDemodVisualQueue = static_cast(getOutputQueue("IQActiveDemodVisualDataOutput")); + iqDataInQueue = std::static_pointer_cast(getInputQueue("IQDataInput")); + iqDataOutQueue = std::static_pointer_cast(getOutputQueue("IQDataOutput")); + iqVisualQueue = std::static_pointer_cast(getOutputQueue("IQVisualDataOutput")); + iqActiveDemodVisualQueue = std::static_pointer_cast(getOutputQueue("IQActiveDemodVisualDataOutput")); while (!stopping) { SDRThreadIQDataPtr data_in; diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 2f7ad3e..8dd7693 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -23,10 +23,10 @@ public: void setIQVisualRange(long long frequency, int bandwidth); protected: - SDRThreadIQDataQueue *iqDataInQueue; - DemodulatorThreadInputQueue *iqDataOutQueue; - DemodulatorThreadInputQueue *iqVisualQueue; - DemodulatorThreadInputQueue *iqActiveDemodVisualQueue; + SDRThreadIQDataQueuePtr iqDataInQueue; + DemodulatorThreadInputQueuePtr iqDataOutQueue; + DemodulatorThreadInputQueuePtr iqVisualQueue; + DemodulatorThreadInputQueuePtr iqActiveDemodVisualQueue; //protects access to demodulators lists and such std::mutex busy_demod; diff --git a/src/sdr/SoapySDRThread.cpp b/src/sdr/SoapySDRThread.cpp index 23d1488..b8c5879 100644 --- a/src/sdr/SoapySDRThread.cpp +++ b/src/sdr/SoapySDRThread.cpp @@ -191,7 +191,7 @@ void SDRThread::assureBufferMinSize(SDRThreadIQData * dataOut, size_t minSize) { //Called in an infinite loop, read SaopySDR device to build // a 'this.numElems' sized batch of samples (SDRThreadIQData) and push it into iqDataOutQueue. //this batch of samples is built to represent 1 frame / TARGET_DISPLAY_FPS. -void SDRThread::readStream(SDRThreadIQDataQueue* iqDataOutQueue) { +void SDRThread::readStream(SDRThreadIQDataQueuePtr iqDataOutQueue) { int flags; long long timeNs; @@ -365,9 +365,10 @@ void SDRThread::readStream(SDRThreadIQDataQueue* iqDataOutQueue) { } void SDRThread::readLoop() { - SDRThreadIQDataQueue* iqDataOutQueue = static_cast( getOutputQueue("IQDataOutput")); + + SDRThreadIQDataQueuePtr iqDataOutQueue = std::static_pointer_cast( getOutputQueue("IQDataOutput")); - if (iqDataOutQueue == NULL) { + if (iqDataOutQueue == nullptr) { return; } diff --git a/src/sdr/SoapySDRThread.h b/src/sdr/SoapySDRThread.h index 93fb381..d704d37 100644 --- a/src/sdr/SoapySDRThread.h +++ b/src/sdr/SoapySDRThread.h @@ -41,12 +41,13 @@ public: }; typedef std::shared_ptr SDRThreadIQDataPtr; typedef ThreadBlockingQueue SDRThreadIQDataQueue; +typedef std::shared_ptr SDRThreadIQDataQueuePtr; class SDRThread : public IOThread { private: bool init(); void deinit(); - void readStream(SDRThreadIQDataQueue* iqDataOutQueue); + void readStream(SDRThreadIQDataQueuePtr iqDataOutQueue); void readLoop(); public: diff --git a/src/util/ThreadBlockingQueue.h b/src/util/ThreadBlockingQueue.h index cf8134c..476b205 100644 --- a/src/util/ThreadBlockingQueue.h +++ b/src/util/ThreadBlockingQueue.h @@ -25,6 +25,8 @@ class ThreadQueueBase { }; +typedef std::shared_ptr ThreadQueueBasePtr; + /** A thread-safe asynchronous blocking queue */ template class ThreadBlockingQueue : public ThreadQueueBase { diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index 907b2db..1f8fc80 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -34,7 +34,7 @@ wxEND_EVENT_TABLE() ScopeCanvas::ScopeCanvas(wxWindow *parent, std::vector dispAttrs) : InteractiveCanvas(parent, dispAttrs), ppmMode(false), ctr(0), ctrTarget(0), dragAccel(0), helpTip("") { glContext = new ScopeContext(this, &wxGetApp().GetContext(this)); - inputData.set_max_num_items(2); + inputData->set_max_num_items(2); bgPanel.setFill(GLPanel::GLPANEL_FILL_GRAD_Y); bgPanel.setSize(1.0, 0.5f); bgPanel.setPosition(0.0, -0.5f); @@ -105,7 +105,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { const wxSize ClientSize = GetClientSize(); ScopeRenderDataPtr avData; - while (inputData.try_pop(avData)) { + while (inputData->try_pop(avData)) { if (!avData->spectrum) { @@ -233,8 +233,8 @@ void ScopeCanvas::OnIdle(wxIdleEvent &event) { event.RequestMore(); } -ScopeRenderDataQueue *ScopeCanvas::getInputQueue() { - return &inputData; +ScopeRenderDataQueuePtr ScopeCanvas::getInputQueue() { + return inputData; } void ScopeCanvas::OnMouseMoved(wxMouseEvent& event) { diff --git a/src/visual/ScopeCanvas.h b/src/visual/ScopeCanvas.h index 7511437..bf16eb9 100644 --- a/src/visual/ScopeCanvas.h +++ b/src/visual/ScopeCanvas.h @@ -8,6 +8,7 @@ #include #include +#include #include "ScopeContext.h" #include "ScopeVisualProcessor.h" @@ -42,7 +43,7 @@ public: void setHelpTip(std::string tip); - ScopeRenderDataQueue *getInputQueue(); + ScopeRenderDataQueuePtr getInputQueue(); private: void OnPaint(wxPaintEvent& event); @@ -54,7 +55,7 @@ private: void OnMouseEnterWindow(wxMouseEvent& event); void OnMouseLeftWindow(wxMouseEvent& event); - ScopeRenderDataQueue inputData; + ScopeRenderDataQueuePtr inputData = std::make_shared(); ScopePanel scopePanel; GLPanel parentPanel; SpectrumPanel spectrumPanel; diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index abfc6f5..7bd75fa 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -37,7 +37,7 @@ SpectrumCanvas::SpectrumCanvas(wxWindow *parent, std::vector dispAttrs) : glContext = new PrimaryGLContext(this, &wxGetApp().GetContext(this)); - visualDataQueue.set_max_num_items(1); + visualDataQueue->set_max_num_items(1); SetCursor(wxCURSOR_SIZEWE); scaleFactor = 1.0; @@ -55,7 +55,7 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { const wxSize ClientSize = GetClientSize(); SpectrumVisualDataPtr vData; - if (visualDataQueue.try_pop(vData)) { + if (visualDataQueue->try_pop(vData)) { if (vData) { spectrumPanel.setPoints(vData->spectrum_points); @@ -286,8 +286,8 @@ void SpectrumCanvas::attachWaterfallCanvas(WaterfallCanvas* canvas_in) { waterfallCanvas = canvas_in; } -SpectrumVisualDataQueue *SpectrumCanvas::getVisualDataQueue() { - return &visualDataQueue; +SpectrumVisualDataQueuePtr SpectrumCanvas::getVisualDataQueue() { + return visualDataQueue; } void SpectrumCanvas::OnMouseRightDown(wxMouseEvent& event) { diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index 68374aa..580d917 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -5,6 +5,7 @@ #include #include +#include #include "InteractiveCanvas.h" #include "PrimaryGLContext.h" @@ -44,7 +45,7 @@ public: void setScaleFactorEnabled(bool en); void setFFTSize(int fftSize); - SpectrumVisualDataQueue *getVisualDataQueue(); + SpectrumVisualDataQueuePtr getVisualDataQueue(); private: void OnPaint(wxPaintEvent& event); @@ -70,7 +71,7 @@ private: int bwChange; bool resetScaleFactor, scaleFactorEnabled; - SpectrumVisualDataQueue visualDataQueue; + SpectrumVisualDataQueuePtr visualDataQueue = std::make_shared(); // event table wxDECLARE_EVENT_TABLE(); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 9d26d56..19f27de 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -99,7 +99,7 @@ void WaterfallCanvas::processInputQueue() { while (lpsIndex >= targetVis) { SpectrumVisualDataPtr vData; - if (visualDataQueue.try_pop(vData)) { + if (visualDataQueue->try_pop(vData)) { if (vData) { if (vData->spectrum_points.size() == fft_size * 2) { @@ -880,8 +880,8 @@ void WaterfallCanvas::OnMouseRightReleased(wxMouseEvent& event) { mouseZoom = 1.0; } -SpectrumVisualDataQueue *WaterfallCanvas::getVisualDataQueue() { - return &visualDataQueue; +SpectrumVisualDataQueuePtr WaterfallCanvas::getVisualDataQueue() { + return visualDataQueue; } void WaterfallCanvas::updateCenterFrequency(long long freq) { @@ -915,7 +915,7 @@ void WaterfallCanvas::setLinesPerSecond(int lps) { linesPerSecond = lps; //empty all - visualDataQueue.flush(); + visualDataQueue->flush(); } void WaterfallCanvas::setMinBandwidth(int min) { diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 4f3ed31..21dea27 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -8,7 +8,7 @@ #include #include - +#include #include "InteractiveCanvas.h" #include "MouseTracker.h" #include "SpectrumCanvas.h" @@ -31,7 +31,7 @@ public: void attachSpectrumCanvas(SpectrumCanvas *canvas_in); void processInputQueue(); - SpectrumVisualDataQueue *getVisualDataQueue(); + SpectrumVisualDataQueuePtr getVisualDataQueue(); void setLinesPerSecond(int lps); void setMinBandwidth(int min); @@ -88,7 +88,8 @@ private: float scaleMove; int dragBW; - SpectrumVisualDataQueue visualDataQueue; + SpectrumVisualDataQueuePtr visualDataQueue = std::make_shared(); + Timer gTimer; double lpsIndex; bool preBuf;