From 560eec1336e032c6ef2dfc37c84b0ecc7b18d01a Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Sat, 1 Aug 2015 11:03:00 -0400 Subject: [PATCH] ScopeVisualProcessor now working --- src/AppFrame.cpp | 1 + src/CubicSDR.cpp | 6 ++++ src/CubicSDR.h | 5 +++ src/demod/DemodulatorInstance.cpp | 10 +++--- src/demod/DemodulatorInstance.h | 2 +- src/process/ScopeVisualProcessor.cpp | 2 +- src/process/VisualProcessor.h | 6 ++-- src/visual/ScopeCanvas.cpp | 51 +++++++++++++--------------- src/visual/ScopeCanvas.h | 8 ++--- 9 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index e345bba..ea7910f 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -91,6 +91,7 @@ AppFrame::AppFrame() : scopeCanvas = new ScopeCanvas(this, attribList); demodScopeTray->Add(scopeCanvas, 8, wxEXPAND | wxALL, 0); + wxGetApp().getScopeProcessor()->attachOutput(scopeCanvas->getInputQueue()); demodScopeTray->AddSpacer(1); diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 49658b2..f17cec3 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -58,6 +58,8 @@ bool CubicSDR::OnInit() { pipeAudioVisualData = new DemodulatorThreadOutputQueue(); pipeAudioVisualData->set_max_num_items(1); + scopeProcessor.setInput(pipeAudioVisualData); + // I/Q Data pipeSDRIQData = new SDRThreadIQDataQueue; pipeSDRCommand = new SDRThreadCommandQueue(); @@ -248,6 +250,10 @@ long long CubicSDR::getFrequency() { return frequency; } +ScopeVisualProcessor *CubicSDR::getScopeProcessor() { + return &scopeProcessor; +} + DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { return pipeAudioVisualData; } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 556773d..6d4c4c8 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -16,6 +16,7 @@ #include "DemodulatorMgr.h" #include "AppConfig.h" #include "AppFrame.h" +#include "ScopeVisualProcessor.h" #include @@ -52,6 +53,8 @@ public: void setDevice(int deviceId); int getDevice(); + ScopeVisualProcessor *getScopeProcessor(); + DemodulatorThreadOutputQueue* getAudioVisualQueue(); DemodulatorThreadInputQueue* getIQVisualQueue(); DemodulatorMgr &getDemodMgr(); @@ -92,6 +95,8 @@ private: DemodulatorThreadInputQueue* pipeIQVisualData; DemodulatorThreadOutputQueue* pipeAudioVisualData; + ScopeVisualProcessor scopeProcessor; + std::thread *t_SDR; std::thread *t_PostSDR; }; diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index d39dcb4..c92f5b5 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -1,7 +1,7 @@ #include "DemodulatorInstance.h" DemodulatorInstance::DemodulatorInstance() : - pipeIQInputData(NULL), demodulatorThread(NULL), t_PreDemod(NULL), t_Demod(NULL), t_Audio(NULL), currentAudioGain(1.0) { + t_PreDemod(NULL), pipeIQInputData(NULL), demodulatorThread(NULL), t_Demod(NULL), t_Audio(NULL), currentAudioGain(1.0) { terminated.store(true); audioTerminated.store(true); @@ -30,17 +30,17 @@ DemodulatorInstance::DemodulatorInstance() : demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify); demodulatorPreThread->setInputQueue("CommandQueue",pipeDemodCommand); - audioInputQueue = new AudioThreadInputQueue; + pipeAudioData = new AudioThreadInputQueue; threadQueueControl = new DemodulatorThreadControlCommandQueue; demodulatorThread = new DemodulatorThread(); demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData); demodulatorThread->setInputQueue("ControlQueue",threadQueueControl); demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify); - demodulatorThread->setOutputQueue("AudioDataOutput", audioInputQueue); + demodulatorThread->setOutputQueue("AudioDataOutput", pipeAudioData); audioThread = new AudioThread(); - audioThread->setInputQueue("AudioDataInput", audioInputQueue); + audioThread->setInputQueue("AudioDataInput", pipeAudioData); audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify); currentDemodType = demodulatorThread->getDemodulatorType(); @@ -55,7 +55,7 @@ DemodulatorInstance::~DemodulatorInstance() { delete pipeDemodCommand; delete pipeDemodNotify; delete threadQueueControl; - delete audioInputQueue; + delete pipeAudioData; } void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index acd28ad..d211746 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -18,7 +18,6 @@ public: std::thread *t_Demod; #endif - AudioThreadInputQueue *audioInputQueue; AudioThread *audioThread; std::thread *t_Audio; @@ -80,6 +79,7 @@ public: protected: DemodulatorThreadInputQueue* pipeIQInputData; DemodulatorThreadPostInputQueue* pipeIQDemodData; + AudioThreadInputQueue *pipeAudioData; DemodulatorThreadCommandQueue* pipeDemodCommand; DemodulatorThreadCommandQueue* pipeDemodNotify; DemodulatorPreThread *demodulatorPreThread; diff --git a/src/process/ScopeVisualProcessor.cpp b/src/process/ScopeVisualProcessor.cpp index c3ffbc9..4eff90d 100644 --- a/src/process/ScopeVisualProcessor.cpp +++ b/src/process/ScopeVisualProcessor.cpp @@ -1,7 +1,7 @@ #include "ScopeVisualProcessor.h" void ScopeVisualProcessor::process() { - if (isOutputEmpty()) { + if (!isOutputEmpty()) { return; } if (!input->empty()) { diff --git a/src/process/VisualProcessor.h b/src/process/VisualProcessor.h index f84c32d..4f8c898 100644 --- a/src/process/VisualProcessor.h +++ b/src/process/VisualProcessor.h @@ -52,7 +52,7 @@ protected: void distribute(OutputDataType *output) { // distribute outputs output->setRefCount(outputs.size()); - for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { if ((*outputs_i)->full()) { output->decRefCount(); } else { @@ -62,7 +62,7 @@ protected: } bool isOutputEmpty() { - for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { if (!(*outputs_i)->empty()) { return false; } @@ -71,7 +71,7 @@ protected: } bool isAnyOutputEmpty() { - for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { if ((*outputs_i)->empty()) { return true; } diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index c80cc54..5c6bd54 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -21,19 +21,16 @@ wxEND_EVENT_TABLE() ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), parent(parent), stereo(false), ppmMode(false) { + wxFULL_REPAINT_ON_RESIZE), stereo(false), ppmMode(false) { glContext = new ScopeContext(this, &wxGetApp().GetContext(this)); + inputData.set_max_num_items(1); } ScopeCanvas::~ScopeCanvas() { } -void ScopeCanvas::setWaveformPoints(std::vector &waveform_points_in) { - waveform_points = waveform_points_in; -} - void ScopeCanvas::setStereo(bool state) { stereo = state; } @@ -58,30 +55,26 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { #endif const wxSize ClientSize = GetClientSize(); - if (!wxGetApp().getAudioVisualQueue()->empty()) { - AudioThreadInput *demodAudioData; - wxGetApp().getAudioVisualQueue()->pop(demodAudioData); + wxGetApp().getScopeProcessor()->run(); + if (!inputData.empty()) { + ScopeRenderData *avData; + inputData.pop(avData); - int iMax = demodAudioData?demodAudioData->data.size():0; - - if (demodAudioData && iMax) { - if (waveform_points.size() != iMax * 2) { - waveform_points.resize(iMax * 2); - } - - demodAudioData->busy_update.lock(); - - for (int i = 0; i < iMax; i++) { - waveform_points[i * 2 + 1] = demodAudioData->data[i] * 0.5f; - waveform_points[i * 2] = ((double) i / (double) iMax); - } - - demodAudioData->busy_update.unlock(); - - setStereo(demodAudioData->channels == 2); - } else { - std::cout << "Incoming Demodulator data empty?" << std::endl; + if (!avData) { + return; } + + int iMax = avData->waveform_points.size(); + + if (!iMax) { + avData->decRefCount(); + return; + } + + waveform_points.assign(avData->waveform_points.begin(),avData->waveform_points.end()); + setStereo(avData->channels == 2); + + avData->decRefCount(); } glContext->SetCurrent(*this); @@ -103,3 +96,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { void ScopeCanvas::OnIdle(wxIdleEvent &event) { Refresh(false); } + +ScopeRenderDataQueue *ScopeCanvas::getInputQueue() { + return &inputData; +} diff --git a/src/visual/ScopeCanvas.h b/src/visual/ScopeCanvas.h index cb24fee..23203b7 100644 --- a/src/visual/ScopeCanvas.h +++ b/src/visual/ScopeCanvas.h @@ -7,6 +7,7 @@ #include #include "ScopeContext.h" +#include "ScopeVisualProcessor.h" #include "fftw3.h" class ScopeCanvas: public wxGLCanvas { @@ -16,19 +17,18 @@ public: ScopeCanvas(wxWindow *parent, int *attribList = NULL); ~ScopeCanvas(); - void setWaveformPoints(std::vector &waveform_points_in); void setStereo(bool state); void setDeviceName(std::string device_name); void setPPMMode(bool ppmMode); bool getPPMMode(); + ScopeRenderDataQueue *getInputQueue(); + private: void OnPaint(wxPaintEvent& event); - void OnIdle(wxIdleEvent &event); - wxWindow *parent; - + ScopeRenderDataQueue inputData; ScopeContext *glContext; std::string deviceName; bool stereo;