mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-27 06:08:37 -05:00
ScopeVisualProcessor now working
This commit is contained in:
parent
cd0adb0339
commit
560eec1336
@ -91,6 +91,7 @@ AppFrame::AppFrame() :
|
|||||||
|
|
||||||
scopeCanvas = new ScopeCanvas(this, attribList);
|
scopeCanvas = new ScopeCanvas(this, attribList);
|
||||||
demodScopeTray->Add(scopeCanvas, 8, wxEXPAND | wxALL, 0);
|
demodScopeTray->Add(scopeCanvas, 8, wxEXPAND | wxALL, 0);
|
||||||
|
wxGetApp().getScopeProcessor()->attachOutput(scopeCanvas->getInputQueue());
|
||||||
|
|
||||||
demodScopeTray->AddSpacer(1);
|
demodScopeTray->AddSpacer(1);
|
||||||
|
|
||||||
|
@ -58,6 +58,8 @@ bool CubicSDR::OnInit() {
|
|||||||
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
|
pipeAudioVisualData = new DemodulatorThreadOutputQueue();
|
||||||
pipeAudioVisualData->set_max_num_items(1);
|
pipeAudioVisualData->set_max_num_items(1);
|
||||||
|
|
||||||
|
scopeProcessor.setInput(pipeAudioVisualData);
|
||||||
|
|
||||||
// I/Q Data
|
// I/Q Data
|
||||||
pipeSDRIQData = new SDRThreadIQDataQueue;
|
pipeSDRIQData = new SDRThreadIQDataQueue;
|
||||||
pipeSDRCommand = new SDRThreadCommandQueue();
|
pipeSDRCommand = new SDRThreadCommandQueue();
|
||||||
@ -248,6 +250,10 @@ long long CubicSDR::getFrequency() {
|
|||||||
return frequency;
|
return frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScopeVisualProcessor *CubicSDR::getScopeProcessor() {
|
||||||
|
return &scopeProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
|
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
|
||||||
return pipeAudioVisualData;
|
return pipeAudioVisualData;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "DemodulatorMgr.h"
|
#include "DemodulatorMgr.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include "AppFrame.h"
|
#include "AppFrame.h"
|
||||||
|
#include "ScopeVisualProcessor.h"
|
||||||
|
|
||||||
#include <wx/cmdline.h>
|
#include <wx/cmdline.h>
|
||||||
|
|
||||||
@ -52,6 +53,8 @@ public:
|
|||||||
void setDevice(int deviceId);
|
void setDevice(int deviceId);
|
||||||
int getDevice();
|
int getDevice();
|
||||||
|
|
||||||
|
ScopeVisualProcessor *getScopeProcessor();
|
||||||
|
|
||||||
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
||||||
DemodulatorThreadInputQueue* getIQVisualQueue();
|
DemodulatorThreadInputQueue* getIQVisualQueue();
|
||||||
DemodulatorMgr &getDemodMgr();
|
DemodulatorMgr &getDemodMgr();
|
||||||
@ -92,6 +95,8 @@ private:
|
|||||||
DemodulatorThreadInputQueue* pipeIQVisualData;
|
DemodulatorThreadInputQueue* pipeIQVisualData;
|
||||||
DemodulatorThreadOutputQueue* pipeAudioVisualData;
|
DemodulatorThreadOutputQueue* pipeAudioVisualData;
|
||||||
|
|
||||||
|
ScopeVisualProcessor scopeProcessor;
|
||||||
|
|
||||||
std::thread *t_SDR;
|
std::thread *t_SDR;
|
||||||
std::thread *t_PostSDR;
|
std::thread *t_PostSDR;
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "DemodulatorInstance.h"
|
#include "DemodulatorInstance.h"
|
||||||
|
|
||||||
DemodulatorInstance::DemodulatorInstance() :
|
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);
|
terminated.store(true);
|
||||||
audioTerminated.store(true);
|
audioTerminated.store(true);
|
||||||
@ -30,17 +30,17 @@ DemodulatorInstance::DemodulatorInstance() :
|
|||||||
demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
|
demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
|
||||||
demodulatorPreThread->setInputQueue("CommandQueue",pipeDemodCommand);
|
demodulatorPreThread->setInputQueue("CommandQueue",pipeDemodCommand);
|
||||||
|
|
||||||
audioInputQueue = new AudioThreadInputQueue;
|
pipeAudioData = new AudioThreadInputQueue;
|
||||||
threadQueueControl = new DemodulatorThreadControlCommandQueue;
|
threadQueueControl = new DemodulatorThreadControlCommandQueue;
|
||||||
|
|
||||||
demodulatorThread = new DemodulatorThread();
|
demodulatorThread = new DemodulatorThread();
|
||||||
demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData);
|
demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData);
|
||||||
demodulatorThread->setInputQueue("ControlQueue",threadQueueControl);
|
demodulatorThread->setInputQueue("ControlQueue",threadQueueControl);
|
||||||
demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
|
demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
|
||||||
demodulatorThread->setOutputQueue("AudioDataOutput", audioInputQueue);
|
demodulatorThread->setOutputQueue("AudioDataOutput", pipeAudioData);
|
||||||
|
|
||||||
audioThread = new AudioThread();
|
audioThread = new AudioThread();
|
||||||
audioThread->setInputQueue("AudioDataInput", audioInputQueue);
|
audioThread->setInputQueue("AudioDataInput", pipeAudioData);
|
||||||
audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify);
|
audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify);
|
||||||
|
|
||||||
currentDemodType = demodulatorThread->getDemodulatorType();
|
currentDemodType = demodulatorThread->getDemodulatorType();
|
||||||
@ -55,7 +55,7 @@ DemodulatorInstance::~DemodulatorInstance() {
|
|||||||
delete pipeDemodCommand;
|
delete pipeDemodCommand;
|
||||||
delete pipeDemodNotify;
|
delete pipeDemodNotify;
|
||||||
delete threadQueueControl;
|
delete threadQueueControl;
|
||||||
delete audioInputQueue;
|
delete pipeAudioData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
|
||||||
|
@ -18,7 +18,6 @@ public:
|
|||||||
std::thread *t_Demod;
|
std::thread *t_Demod;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AudioThreadInputQueue *audioInputQueue;
|
|
||||||
AudioThread *audioThread;
|
AudioThread *audioThread;
|
||||||
std::thread *t_Audio;
|
std::thread *t_Audio;
|
||||||
|
|
||||||
@ -80,6 +79,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
DemodulatorThreadInputQueue* pipeIQInputData;
|
DemodulatorThreadInputQueue* pipeIQInputData;
|
||||||
DemodulatorThreadPostInputQueue* pipeIQDemodData;
|
DemodulatorThreadPostInputQueue* pipeIQDemodData;
|
||||||
|
AudioThreadInputQueue *pipeAudioData;
|
||||||
DemodulatorThreadCommandQueue* pipeDemodCommand;
|
DemodulatorThreadCommandQueue* pipeDemodCommand;
|
||||||
DemodulatorThreadCommandQueue* pipeDemodNotify;
|
DemodulatorThreadCommandQueue* pipeDemodNotify;
|
||||||
DemodulatorPreThread *demodulatorPreThread;
|
DemodulatorPreThread *demodulatorPreThread;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "ScopeVisualProcessor.h"
|
#include "ScopeVisualProcessor.h"
|
||||||
|
|
||||||
void ScopeVisualProcessor::process() {
|
void ScopeVisualProcessor::process() {
|
||||||
if (isOutputEmpty()) {
|
if (!isOutputEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!input->empty()) {
|
if (!input->empty()) {
|
||||||
|
@ -52,7 +52,7 @@ protected:
|
|||||||
void distribute(OutputDataType *output) {
|
void distribute(OutputDataType *output) {
|
||||||
// distribute outputs
|
// distribute outputs
|
||||||
output->setRefCount(outputs.size());
|
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()) {
|
if ((*outputs_i)->full()) {
|
||||||
output->decRefCount();
|
output->decRefCount();
|
||||||
} else {
|
} else {
|
||||||
@ -62,7 +62,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isOutputEmpty() {
|
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()) {
|
if (!(*outputs_i)->empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isAnyOutputEmpty() {
|
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()) {
|
if ((*outputs_i)->empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,16 @@ wxEND_EVENT_TABLE()
|
|||||||
|
|
||||||
ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) :
|
ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) :
|
||||||
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
|
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));
|
glContext = new ScopeContext(this, &wxGetApp().GetContext(this));
|
||||||
|
inputData.set_max_num_items(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeCanvas::~ScopeCanvas() {
|
ScopeCanvas::~ScopeCanvas() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScopeCanvas::setWaveformPoints(std::vector<float> &waveform_points_in) {
|
|
||||||
waveform_points = waveform_points_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScopeCanvas::setStereo(bool state) {
|
void ScopeCanvas::setStereo(bool state) {
|
||||||
stereo = state;
|
stereo = state;
|
||||||
}
|
}
|
||||||
@ -58,30 +55,26 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
#endif
|
#endif
|
||||||
const wxSize ClientSize = GetClientSize();
|
const wxSize ClientSize = GetClientSize();
|
||||||
|
|
||||||
if (!wxGetApp().getAudioVisualQueue()->empty()) {
|
wxGetApp().getScopeProcessor()->run();
|
||||||
AudioThreadInput *demodAudioData;
|
if (!inputData.empty()) {
|
||||||
wxGetApp().getAudioVisualQueue()->pop(demodAudioData);
|
ScopeRenderData *avData;
|
||||||
|
inputData.pop(avData);
|
||||||
|
|
||||||
int iMax = demodAudioData?demodAudioData->data.size():0;
|
if (!avData) {
|
||||||
|
return;
|
||||||
if (demodAudioData && iMax) {
|
|
||||||
if (waveform_points.size() != iMax * 2) {
|
|
||||||
waveform_points.resize(iMax * 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
demodAudioData->busy_update.lock();
|
int iMax = avData->waveform_points.size();
|
||||||
|
|
||||||
for (int i = 0; i < iMax; i++) {
|
if (!iMax) {
|
||||||
waveform_points[i * 2 + 1] = demodAudioData->data[i] * 0.5f;
|
avData->decRefCount();
|
||||||
waveform_points[i * 2] = ((double) i / (double) iMax);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
demodAudioData->busy_update.unlock();
|
waveform_points.assign(avData->waveform_points.begin(),avData->waveform_points.end());
|
||||||
|
setStereo(avData->channels == 2);
|
||||||
|
|
||||||
setStereo(demodAudioData->channels == 2);
|
avData->decRefCount();
|
||||||
} else {
|
|
||||||
std::cout << "Incoming Demodulator data empty?" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glContext->SetCurrent(*this);
|
glContext->SetCurrent(*this);
|
||||||
@ -103,3 +96,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
|||||||
void ScopeCanvas::OnIdle(wxIdleEvent &event) {
|
void ScopeCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
Refresh(false);
|
Refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScopeRenderDataQueue *ScopeCanvas::getInputQueue() {
|
||||||
|
return &inputData;
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "ScopeContext.h"
|
#include "ScopeContext.h"
|
||||||
|
#include "ScopeVisualProcessor.h"
|
||||||
#include "fftw3.h"
|
#include "fftw3.h"
|
||||||
|
|
||||||
class ScopeCanvas: public wxGLCanvas {
|
class ScopeCanvas: public wxGLCanvas {
|
||||||
@ -16,19 +17,18 @@ public:
|
|||||||
ScopeCanvas(wxWindow *parent, int *attribList = NULL);
|
ScopeCanvas(wxWindow *parent, int *attribList = NULL);
|
||||||
~ScopeCanvas();
|
~ScopeCanvas();
|
||||||
|
|
||||||
void setWaveformPoints(std::vector<float> &waveform_points_in);
|
|
||||||
void setStereo(bool state);
|
void setStereo(bool state);
|
||||||
void setDeviceName(std::string device_name);
|
void setDeviceName(std::string device_name);
|
||||||
void setPPMMode(bool ppmMode);
|
void setPPMMode(bool ppmMode);
|
||||||
bool getPPMMode();
|
bool getPPMMode();
|
||||||
|
|
||||||
|
ScopeRenderDataQueue *getInputQueue();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
|
||||||
void OnIdle(wxIdleEvent &event);
|
void OnIdle(wxIdleEvent &event);
|
||||||
|
|
||||||
wxWindow *parent;
|
ScopeRenderDataQueue inputData;
|
||||||
|
|
||||||
ScopeContext *glContext;
|
ScopeContext *glContext;
|
||||||
std::string deviceName;
|
std::string deviceName;
|
||||||
bool stereo;
|
bool stereo;
|
||||||
|
Loading…
Reference in New Issue
Block a user