mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-23 12:18:37 -05:00
Merge pull request #131 from cjcliffe/waterfall_optimize
Waterfall optimize
This commit is contained in:
commit
8d03c9ef0e
@ -263,6 +263,7 @@ SET (cubicsdr_sources
|
|||||||
src/process/VisualProcessor.cpp
|
src/process/VisualProcessor.cpp
|
||||||
src/process/ScopeVisualProcessor.cpp
|
src/process/ScopeVisualProcessor.cpp
|
||||||
src/process/SpectrumVisualProcessor.cpp
|
src/process/SpectrumVisualProcessor.cpp
|
||||||
|
src/process/FFTVisualDataThread.cpp
|
||||||
src/ui/GLPanel.cpp
|
src/ui/GLPanel.cpp
|
||||||
external/rtaudio/RtAudio.cpp
|
external/rtaudio/RtAudio.cpp
|
||||||
external/lodepng/lodepng.cpp
|
external/lodepng/lodepng.cpp
|
||||||
@ -316,6 +317,7 @@ SET (cubicsdr_headers
|
|||||||
src/process/VisualProcessor.h
|
src/process/VisualProcessor.h
|
||||||
src/process/ScopeVisualProcessor.h
|
src/process/ScopeVisualProcessor.h
|
||||||
src/process/SpectrumVisualProcessor.h
|
src/process/SpectrumVisualProcessor.h
|
||||||
|
src/process/FFTVisualDataThread.h
|
||||||
src/ui/GLPanel.h
|
src/ui/GLPanel.h
|
||||||
src/ui/UITestCanvas.cpp
|
src/ui/UITestCanvas.cpp
|
||||||
src/ui/UITestCanvas.h
|
src/ui/UITestCanvas.h
|
||||||
|
@ -133,15 +133,14 @@ AppFrame::AppFrame() :
|
|||||||
|
|
||||||
wxBoxSizer *wfSizer = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer *wfSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
|
||||||
wxGetApp().getWaterfallProcesor()->setup(2048);
|
|
||||||
waterfallCanvas = new WaterfallCanvas(this, attribList);
|
waterfallCanvas = new WaterfallCanvas(this, attribList);
|
||||||
waterfallCanvas->setup(2048, 512);
|
waterfallCanvas->setup(2048, 512);
|
||||||
|
|
||||||
fftDistrib.setInput(wxGetApp().getWaterfallVisualQueue());
|
waterfallDataThread = new FFTVisualDataThread();
|
||||||
fftDistrib.attachOutput(&fftQueue);
|
t_FFTData = new std::thread(&FFTVisualDataThread::threadMain, waterfallDataThread);
|
||||||
|
|
||||||
wxGetApp().getWaterfallProcesor()->setInput(&fftQueue);
|
waterfallDataThread->setInputQueue("IQDataInput", wxGetApp().getWaterfallVisualQueue());
|
||||||
wxGetApp().getWaterfallProcesor()->attachOutput(waterfallCanvas->getVisualDataQueue());
|
waterfallDataThread->setOutputQueue("FFTDataOutput", waterfallCanvas->getVisualDataQueue());
|
||||||
|
|
||||||
waterfallSpeedMeter = new MeterCanvas(this, attribList);
|
waterfallSpeedMeter = new MeterCanvas(this, attribList);
|
||||||
waterfallSpeedMeter->setHelpTip("Waterfall speed, click or drag to adjust (max 1024 lines per second)");
|
waterfallSpeedMeter->setHelpTip("Waterfall speed, click or drag to adjust (max 1024 lines per second)");
|
||||||
@ -376,7 +375,7 @@ AppFrame::AppFrame() :
|
|||||||
int wflps =wxGetApp().getConfig()->getWaterfallLinesPerSec();
|
int wflps =wxGetApp().getConfig()->getWaterfallLinesPerSec();
|
||||||
|
|
||||||
waterfallSpeedMeter->setLevel(sqrt(wflps));
|
waterfallSpeedMeter->setLevel(sqrt(wflps));
|
||||||
fftDistrib.setLinesPerSecond(wflps);
|
waterfallDataThread->setLinesPerSecond(wflps);
|
||||||
|
|
||||||
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
|
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
|
||||||
|
|
||||||
@ -400,7 +399,8 @@ AppFrame::AppFrame() :
|
|||||||
}
|
}
|
||||||
|
|
||||||
AppFrame::~AppFrame() {
|
AppFrame::~AppFrame() {
|
||||||
|
waterfallDataThread->terminate();
|
||||||
|
t_FFTData->join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -486,7 +486,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) {
|
|||||||
waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
waterfallCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||||
spectrumCanvas->setBandwidth(wxGetApp().getSampleRate());
|
spectrumCanvas->setBandwidth(wxGetApp().getSampleRate());
|
||||||
spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency());
|
||||||
fftDistrib.setLinesPerSecond(DEFAULT_WATERFALL_LPS);
|
waterfallDataThread->setLinesPerSecond(DEFAULT_WATERFALL_LPS);
|
||||||
waterfallSpeedMeter->setLevel(sqrt(DEFAULT_WATERFALL_LPS));
|
waterfallSpeedMeter->setLevel(sqrt(DEFAULT_WATERFALL_LPS));
|
||||||
wxGetApp().getSpectrumProcesor()->setFFTAverageRate(0.65);
|
wxGetApp().getSpectrumProcesor()->setFFTAverageRate(0.65);
|
||||||
spectrumAvgMeter->setLevel(0.65);
|
spectrumAvgMeter->setLevel(0.65);
|
||||||
@ -613,7 +613,7 @@ void AppFrame::OnClose(wxCloseEvent& event) {
|
|||||||
wxGetApp().getConfig()->setSnap(wxGetApp().getFrequencySnap());
|
wxGetApp().getConfig()->setSnap(wxGetApp().getFrequencySnap());
|
||||||
wxGetApp().getConfig()->setCenterFreq(wxGetApp().getFrequency());
|
wxGetApp().getConfig()->setCenterFreq(wxGetApp().getFrequency());
|
||||||
wxGetApp().getConfig()->setSpectrumAvgSpeed(wxGetApp().getSpectrumProcesor()->getFFTAverageRate());
|
wxGetApp().getConfig()->setSpectrumAvgSpeed(wxGetApp().getSpectrumProcesor()->getFFTAverageRate());
|
||||||
wxGetApp().getConfig()->setWaterfallLinesPerSec(fftDistrib.getLinesPerSecond());
|
wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond());
|
||||||
wxGetApp().getConfig()->save();
|
wxGetApp().getConfig()->save();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
@ -746,6 +746,9 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
|||||||
|
|
||||||
if (spectrumAvgMeter->inputChanged()) {
|
if (spectrumAvgMeter->inputChanged()) {
|
||||||
float val = spectrumAvgMeter->getInputValue();
|
float val = spectrumAvgMeter->getInputValue();
|
||||||
|
if (val < 0.01) {
|
||||||
|
val = 0.01;
|
||||||
|
}
|
||||||
spectrumAvgMeter->setLevel(val);
|
spectrumAvgMeter->setLevel(val);
|
||||||
proc->setFFTAverageRate(val);
|
proc->setFFTAverageRate(val);
|
||||||
|
|
||||||
@ -766,51 +769,24 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
|
|||||||
|
|
||||||
dproc->run();
|
dproc->run();
|
||||||
|
|
||||||
SpectrumVisualProcessor *wproc = wxGetApp().getWaterfallProcesor();
|
SpectrumVisualProcessor *wproc = waterfallDataThread->getProcessor();
|
||||||
|
|
||||||
int fftSize = wproc->getDesiredInputSize();
|
|
||||||
|
|
||||||
if (fftSize) {
|
|
||||||
fftDistrib.setFFTSize(fftSize);
|
|
||||||
} else {
|
|
||||||
fftDistrib.setFFTSize(DEFAULT_FFT_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waterfallSpeedMeter->inputChanged()) {
|
if (waterfallSpeedMeter->inputChanged()) {
|
||||||
float val = waterfallSpeedMeter->getInputValue();
|
float val = waterfallSpeedMeter->getInputValue();
|
||||||
waterfallSpeedMeter->setLevel(val);
|
waterfallSpeedMeter->setLevel(val);
|
||||||
fftDistrib.setLinesPerSecond((int)ceil(val*val));
|
waterfallDataThread->setLinesPerSecond((int)ceil(val*val));
|
||||||
wxGetApp().getWaterfallVisualQueue()->set_max_num_items((int)ceil(val*val));
|
|
||||||
|
|
||||||
GetStatusBar()->SetStatusText(wxString::Format(wxT("Waterfall max speed changed to %d lines per second."),(int)ceil(val*val)));
|
GetStatusBar()->SetStatusText(wxString::Format(wxT("Waterfall max speed changed to %d lines per second."),(int)ceil(val*val)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fftDistrib.run();
|
|
||||||
|
|
||||||
wproc->setView(waterfallCanvas->getViewState());
|
wproc->setView(waterfallCanvas->getViewState());
|
||||||
wproc->setBandwidth(waterfallCanvas->getBandwidth());
|
wproc->setBandwidth(waterfallCanvas->getBandwidth());
|
||||||
wproc->setCenterFrequency(waterfallCanvas->getCenterFrequency());
|
wproc->setCenterFrequency(waterfallCanvas->getCenterFrequency());
|
||||||
|
|
||||||
while (!wproc->isInputEmpty()) {
|
|
||||||
wproc->run();
|
|
||||||
}
|
|
||||||
|
|
||||||
waterfallCanvas->processInputQueue();
|
waterfallCanvas->processInputQueue();
|
||||||
demodWaterfallCanvas->processInputQueue();
|
demodWaterfallCanvas->processInputQueue();
|
||||||
|
|
||||||
|
if (!this->IsActive()) {
|
||||||
if (this->IsVisible()) {
|
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
||||||
waterfallCanvas->DoPaint();
|
|
||||||
demodWaterfallCanvas->DoPaint();
|
|
||||||
#ifdef __APPLE__
|
|
||||||
usleep(5000);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#ifndef _WIN32
|
|
||||||
usleep(15000);
|
|
||||||
#else
|
|
||||||
Sleep(15);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event.RequestMore();
|
event.RequestMore();
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
#include "MeterCanvas.h"
|
#include "MeterCanvas.h"
|
||||||
#include "TuningCanvas.h"
|
#include "TuningCanvas.h"
|
||||||
#include "ModeSelectorCanvas.h"
|
#include "ModeSelectorCanvas.h"
|
||||||
#include "UITestCanvas.h"
|
#include "FFTVisualDataThread.h"
|
||||||
|
//#include "UITestCanvas.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -94,8 +95,9 @@ private:
|
|||||||
|
|
||||||
std::string currentSessionFile;
|
std::string currentSessionFile;
|
||||||
|
|
||||||
FFTDataDistributor fftDistrib;
|
FFTVisualDataThread *waterfallDataThread;
|
||||||
DemodulatorThreadInputQueue fftQueue;
|
|
||||||
|
std::thread *t_FFTData;
|
||||||
|
|
||||||
wxDECLARE_EVENT_TABLE();
|
wxDECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "CubicSDR.h"
|
#include "CubicSDR.h"
|
||||||
#include "FrequencyDialog.h"
|
|
||||||
|
|
||||||
#ifdef _OSX_APP_
|
#ifdef _OSX_APP_
|
||||||
#include "CoreFoundation/CoreFoundation.h"
|
#include "CoreFoundation/CoreFoundation.h"
|
||||||
@ -282,10 +281,6 @@ SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcesor() {
|
|||||||
return &demodSpectrumProcessor;
|
return &demodSpectrumProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpectrumVisualProcessor *CubicSDR::getWaterfallProcesor() {
|
|
||||||
return &waterfallProcessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
VisualDataDistributor<DemodulatorThreadIQData> *CubicSDR::getSpectrumDistributor() {
|
VisualDataDistributor<DemodulatorThreadIQData> *CubicSDR::getSpectrumDistributor() {
|
||||||
return &spectrumDistributor;
|
return &spectrumDistributor;
|
||||||
}
|
}
|
||||||
@ -393,8 +388,25 @@ int CubicSDR::getPPM() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CubicSDR::showFrequencyInput() {
|
void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode) {
|
||||||
FrequencyDialog fdialog(appframe, -1, demodMgr.getActiveDemodulator()?_("Set Demodulator Frequency"):_("Set Center Frequency"), demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(320, 75 ));
|
const wxString demodTitle("Set Demodulator Frequency");
|
||||||
|
const wxString freqTitle("Set Center Frequency");
|
||||||
|
const wxString bwTitle("Set Demodulator Bandwidth");
|
||||||
|
|
||||||
|
wxString title;
|
||||||
|
|
||||||
|
switch (targetMode) {
|
||||||
|
case FrequencyDialog::FDIALOG_TARGET_DEFAULT:
|
||||||
|
title = demodMgr.getActiveDemodulator()?demodTitle:freqTitle;
|
||||||
|
break;
|
||||||
|
case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH:
|
||||||
|
title = bwTitle;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrequencyDialog fdialog(appframe, -1, title, demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(320, 75 ), wxDEFAULT_DIALOG_STYLE, targetMode);
|
||||||
fdialog.ShowModal();
|
fdialog.ShowModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "DemodulatorMgr.h"
|
#include "DemodulatorMgr.h"
|
||||||
#include "AppConfig.h"
|
#include "AppConfig.h"
|
||||||
#include "AppFrame.h"
|
#include "AppFrame.h"
|
||||||
|
#include "FrequencyDialog.h"
|
||||||
|
|
||||||
#include "ScopeVisualProcessor.h"
|
#include "ScopeVisualProcessor.h"
|
||||||
#include "SpectrumVisualProcessor.h"
|
#include "SpectrumVisualProcessor.h"
|
||||||
@ -58,7 +59,6 @@ public:
|
|||||||
ScopeVisualProcessor *getScopeProcessor();
|
ScopeVisualProcessor *getScopeProcessor();
|
||||||
SpectrumVisualProcessor *getSpectrumProcesor();
|
SpectrumVisualProcessor *getSpectrumProcesor();
|
||||||
SpectrumVisualProcessor *getDemodSpectrumProcesor();
|
SpectrumVisualProcessor *getDemodSpectrumProcesor();
|
||||||
SpectrumVisualProcessor *getWaterfallProcesor();
|
|
||||||
VisualDataDistributor<DemodulatorThreadIQData> *getSpectrumDistributor();
|
VisualDataDistributor<DemodulatorThreadIQData> *getSpectrumDistributor();
|
||||||
|
|
||||||
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
DemodulatorThreadOutputQueue* getAudioVisualQueue();
|
||||||
@ -78,7 +78,7 @@ public:
|
|||||||
void setPPM(int ppm_in);
|
void setPPM(int ppm_in);
|
||||||
int getPPM();
|
int getPPM();
|
||||||
|
|
||||||
void showFrequencyInput();
|
void showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode = FrequencyDialog::FDIALOG_TARGET_DEFAULT);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppFrame *appframe;
|
AppFrame *appframe;
|
||||||
@ -107,7 +107,6 @@ private:
|
|||||||
|
|
||||||
ScopeVisualProcessor scopeProcessor;
|
ScopeVisualProcessor scopeProcessor;
|
||||||
SpectrumVisualProcessor spectrumProcessor;
|
SpectrumVisualProcessor spectrumProcessor;
|
||||||
SpectrumVisualProcessor waterfallProcessor;
|
|
||||||
SpectrumVisualProcessor demodSpectrumProcessor;
|
SpectrumVisualProcessor demodSpectrumProcessor;
|
||||||
|
|
||||||
VisualDataDistributor<DemodulatorThreadIQData> spectrumDistributor;
|
VisualDataDistributor<DemodulatorThreadIQData> spectrumDistributor;
|
||||||
|
@ -10,16 +10,23 @@ EVT_CHAR_HOOK(FrequencyDialog::OnChar)
|
|||||||
wxEND_EVENT_TABLE()
|
wxEND_EVENT_TABLE()
|
||||||
|
|
||||||
FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod, const wxPoint & position,
|
FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod, const wxPoint & position,
|
||||||
const wxSize & size, long style) :
|
const wxSize & size, long style, FrequencyDialogTarget targetMode) :
|
||||||
wxDialog(parent, id, title, position, size, style) {
|
wxDialog(parent, id, title, position, size, style) {
|
||||||
wxString freqStr;
|
wxString freqStr;
|
||||||
activeDemod = demod;
|
activeDemod = demod;
|
||||||
|
this->targetMode = targetMode;
|
||||||
|
|
||||||
|
if (targetMode == FDIALOG_TARGET_DEFAULT) {
|
||||||
if (activeDemod) {
|
if (activeDemod) {
|
||||||
freqStr = frequencyToStr(activeDemod->getFrequency());
|
freqStr = frequencyToStr(activeDemod->getFrequency());
|
||||||
} else {
|
} else {
|
||||||
freqStr = frequencyToStr(wxGetApp().getFrequency());
|
freqStr = frequencyToStr(wxGetApp().getFrequency());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetMode == FDIALOG_TARGET_BANDWIDTH) {
|
||||||
|
freqStr = frequencyToStr(wxGetApp().getDemodMgr().getLastBandwidth());
|
||||||
|
}
|
||||||
|
|
||||||
dialogText = new wxTextCtrl(this, wxID_FREQ_INPUT, freqStr, wxPoint(6, 1), wxSize(size.GetWidth() - 20, size.GetHeight() - 70),
|
dialogText = new wxTextCtrl(this, wxID_FREQ_INPUT, freqStr, wxPoint(6, 1), wxSize(size.GetWidth() - 20, size.GetHeight() - 70),
|
||||||
wxTE_PROCESS_ENTER);
|
wxTE_PROCESS_ENTER);
|
||||||
@ -109,6 +116,7 @@ void FrequencyDialog::OnChar(wxKeyEvent& event) {
|
|||||||
case WXK_NUMPAD_ENTER:
|
case WXK_NUMPAD_ENTER:
|
||||||
// Do Stuff
|
// Do Stuff
|
||||||
freq = strToFrequency(dialogText->GetValue().ToStdString());
|
freq = strToFrequency(dialogText->GetValue().ToStdString());
|
||||||
|
if (targetMode == FDIALOG_TARGET_DEFAULT) {
|
||||||
if (activeDemod) {
|
if (activeDemod) {
|
||||||
activeDemod->setTracking(true);
|
activeDemod->setTracking(true);
|
||||||
activeDemod->setFollow(true);
|
activeDemod->setFollow(true);
|
||||||
@ -117,6 +125,14 @@ void FrequencyDialog::OnChar(wxKeyEvent& event) {
|
|||||||
} else {
|
} else {
|
||||||
wxGetApp().setFrequency(freq);
|
wxGetApp().setFrequency(freq);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (targetMode == FDIALOG_TARGET_BANDWIDTH) {
|
||||||
|
if (activeDemod) {
|
||||||
|
activeDemod->setBandwidth(freq);
|
||||||
|
} else {
|
||||||
|
wxGetApp().getDemodMgr().setLastBandwidth(freq);
|
||||||
|
}
|
||||||
|
}
|
||||||
Close();
|
Close();
|
||||||
break;
|
break;
|
||||||
case WXK_ESCAPE:
|
case WXK_ESCAPE:
|
||||||
|
@ -11,12 +11,13 @@
|
|||||||
class FrequencyDialog: public wxDialog
|
class FrequencyDialog: public wxDialog
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef enum FrequencyDialogTarget { FDIALOG_TARGET_DEFAULT, FDIALOG_TARGET_CENTERFREQ, FDIALOG_TARGET_FREQ, FDIALOG_TARGET_BANDWIDTH } FrequencyDialogTarget;
|
||||||
FrequencyDialog ( wxWindow * parent, wxWindowID id, const wxString & title,
|
FrequencyDialog ( wxWindow * parent, wxWindowID id, const wxString & title,
|
||||||
DemodulatorInstance *demod = NULL,
|
DemodulatorInstance *demod = NULL,
|
||||||
const wxPoint & pos = wxDefaultPosition,
|
const wxPoint & pos = wxDefaultPosition,
|
||||||
const wxSize & size = wxDefaultSize,
|
const wxSize & size = wxDefaultSize,
|
||||||
long style = wxDEFAULT_DIALOG_STYLE );
|
long style = wxDEFAULT_DIALOG_STYLE,
|
||||||
|
FrequencyDialogTarget targetMode = FDIALOG_TARGET_DEFAULT);
|
||||||
|
|
||||||
wxTextCtrl * dialogText;
|
wxTextCtrl * dialogText;
|
||||||
|
|
||||||
@ -28,5 +29,6 @@ private:
|
|||||||
void OnEnter ( wxCommandEvent &event );
|
void OnEnter ( wxCommandEvent &event );
|
||||||
void OnChar ( wxKeyEvent &event );
|
void OnChar ( wxKeyEvent &event );
|
||||||
std::string& filterChars(std::string& s, const std::string& allowed);
|
std::string& filterChars(std::string& s, const std::string& allowed);
|
||||||
|
FrequencyDialogTarget targetMode;
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
64
src/process/FFTVisualDataThread.cpp
Normal file
64
src/process/FFTVisualDataThread.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "FFTVisualDataThread.h"
|
||||||
|
#include "CubicSDR.h"
|
||||||
|
|
||||||
|
FFTVisualDataThread::FFTVisualDataThread() : linesPerSecond(DEFAULT_WATERFALL_LPS) {
|
||||||
|
lpsChanged.store(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
FFTVisualDataThread::~FFTVisualDataThread() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FFTVisualDataThread::setLinesPerSecond(int lps) {
|
||||||
|
linesPerSecond.store(lps);
|
||||||
|
lpsChanged.store(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FFTVisualDataThread::getLinesPerSecond() {
|
||||||
|
return linesPerSecond.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
SpectrumVisualProcessor *FFTVisualDataThread::getProcessor() {
|
||||||
|
return &wproc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FFTVisualDataThread::run() {
|
||||||
|
DemodulatorThreadInputQueue *pipeIQDataIn = (DemodulatorThreadInputQueue *)getInputQueue("IQDataInput");
|
||||||
|
SpectrumVisualDataQueue *pipeFFTDataOut = (SpectrumVisualDataQueue *)getOutputQueue("FFTDataOutput");
|
||||||
|
|
||||||
|
fftDistrib.setInput(pipeIQDataIn);
|
||||||
|
fftDistrib.attachOutput(&fftQueue);
|
||||||
|
wproc.setInput(&fftQueue);
|
||||||
|
wproc.attachOutput(pipeFFTDataOut);
|
||||||
|
wproc.setup(2048);
|
||||||
|
|
||||||
|
std::cout << "FFT visual data thread started." << std::endl;
|
||||||
|
|
||||||
|
while(!terminated) {
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(12));
|
||||||
|
|
||||||
|
int fftSize = wproc.getDesiredInputSize();
|
||||||
|
|
||||||
|
if (fftSize) {
|
||||||
|
fftDistrib.setFFTSize(fftSize);
|
||||||
|
} else {
|
||||||
|
fftDistrib.setFFTSize(DEFAULT_FFT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpsChanged.load()) {
|
||||||
|
fftDistrib.setLinesPerSecond(linesPerSecond.load());
|
||||||
|
pipeIQDataIn->set_max_num_items(linesPerSecond.load());
|
||||||
|
lpsChanged.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fftDistrib.run();
|
||||||
|
|
||||||
|
while (!wproc.isInputEmpty()) {
|
||||||
|
wproc.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "FFT visual data thread terminated." << std::endl;
|
||||||
|
}
|
||||||
|
|
24
src/process/FFTVisualDataThread.h
Normal file
24
src/process/FFTVisualDataThread.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IOThread.h"
|
||||||
|
#include "SpectrumVisualProcessor.h"
|
||||||
|
|
||||||
|
class FFTVisualDataThread : public IOThread {
|
||||||
|
public:
|
||||||
|
FFTVisualDataThread();
|
||||||
|
~FFTVisualDataThread();
|
||||||
|
|
||||||
|
void setLinesPerSecond(int lps);
|
||||||
|
int getLinesPerSecond();
|
||||||
|
SpectrumVisualProcessor *getProcessor();
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FFTDataDistributor fftDistrib;
|
||||||
|
DemodulatorThreadInputQueue fftQueue;
|
||||||
|
SpectrumVisualProcessor wproc;
|
||||||
|
|
||||||
|
std::atomic_int linesPerSecond;
|
||||||
|
std::atomic_bool lpsChanged;
|
||||||
|
};
|
@ -111,7 +111,10 @@ protected:
|
|||||||
|
|
||||||
if (inp) {
|
if (inp) {
|
||||||
if (inp->data.size() >= fftSize) {
|
if (inp->data.size() >= fftSize) {
|
||||||
for (int i = 0, iMax = inp->data.size()-fftSize; i <= iMax; i += fftSize) {
|
if (lineRateAccum + (lineRateStep * floor((double)inp->data.size()/(double)fftSize)) < 1.0) {
|
||||||
|
// move along, nothing to see here..
|
||||||
|
lineRateAccum += (lineRateStep * inp->data.size()/fftSize);
|
||||||
|
} else for (int i = 0, iMax = inp->data.size()-fftSize; i <= iMax; i += fftSize) {
|
||||||
lineRateAccum += lineRateStep;
|
lineRateAccum += lineRateStep;
|
||||||
|
|
||||||
if (lineRateAccum >= 1.0) {
|
if (lineRateAccum >= 1.0) {
|
||||||
|
@ -32,9 +32,8 @@ void initGLExtensions() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GLubyte *extensions = glGetString(GL_EXTENSIONS);
|
// const GLubyte *extensions = glGetString(GL_EXTENSIONS);
|
||||||
|
// std::cout << std::endl << "Supported GL Extensions: " << std::endl << extensions << std::endl << std::endl;
|
||||||
std::cout << std::endl << "Supported GL Extensions: " << std::endl << extensions << std::endl << std::endl;
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
const GLint interval = 2;
|
const GLint interval = 2;
|
||||||
|
@ -297,7 +297,7 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) {
|
|||||||
setStatusText("Click, wheel or drag a digit to change frequency; SPACE for direct input. Right click to set/clear snap. Hold ALT to change PPM. Hold SHIFT to disable carry.");
|
setStatusText("Click, wheel or drag a digit to change frequency; SPACE for direct input. Right click to set/clear snap. Hold ALT to change PPM. Hold SHIFT to disable carry.");
|
||||||
break;
|
break;
|
||||||
case TUNING_HOVER_BW:
|
case TUNING_HOVER_BW:
|
||||||
setStatusText("Click, wheel or drag a digit to change bandwidth. Hold SHIFT to disable carry.");
|
setStatusText("Click, wheel or drag a digit to change bandwidth; SPACE for direct input. Hold SHIFT to disable carry.");
|
||||||
break;
|
break;
|
||||||
case TUNING_HOVER_CENTER:
|
case TUNING_HOVER_CENTER:
|
||||||
setStatusText("Click, wheel or drag a digit to change center frequency; SPACE for direct input. Hold SHIFT to disable carry.");
|
setStatusText("Click, wheel or drag a digit to change center frequency; SPACE for direct input. Hold SHIFT to disable carry.");
|
||||||
@ -407,8 +407,12 @@ void TuningCanvas::setHelpTip(std::string tip) {
|
|||||||
void TuningCanvas::OnKeyDown(wxKeyEvent& event) {
|
void TuningCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||||
InteractiveCanvas::OnKeyDown(event);
|
InteractiveCanvas::OnKeyDown(event);
|
||||||
|
|
||||||
if (event.GetKeyCode() == WXK_SPACE && (hoverState == TUNING_HOVER_CENTER || hoverState == TUNING_HOVER_FREQ)) {
|
if (event.GetKeyCode() == WXK_SPACE) {
|
||||||
wxGetApp().showFrequencyInput();
|
if (hoverState == TUNING_HOVER_CENTER || hoverState == TUNING_HOVER_FREQ) {
|
||||||
|
wxGetApp().showFrequencyInput(FrequencyDialog::FDIALOG_TARGET_DEFAULT);
|
||||||
|
} else if (hoverState == TUNING_HOVER_BW) {
|
||||||
|
wxGetApp().showFrequencyInput(FrequencyDialog::FDIALOG_TARGET_BANDWIDTH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,12 +88,8 @@ void WaterfallCanvas::processInputQueue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||||
// event.Skip();
|
// wxClientDC dc(this);
|
||||||
}
|
wxPaintDC dc(this);
|
||||||
|
|
||||||
void WaterfallCanvas::DoPaint() {
|
|
||||||
wxClientDC dc(this);
|
|
||||||
// wxPaintDC dc(this);
|
|
||||||
|
|
||||||
const wxSize ClientSize = GetClientSize();
|
const wxSize ClientSize = GetClientSize();
|
||||||
long double currentZoom = zoom;
|
long double currentZoom = zoom;
|
||||||
@ -359,9 +355,9 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
|
void WaterfallCanvas::OnIdle(wxIdleEvent &event) {
|
||||||
// Refresh();
|
Refresh();
|
||||||
// event.RequestMore();
|
event.RequestMore();
|
||||||
event.Skip();
|
// event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
|
void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||||
|
@ -28,7 +28,6 @@ public:
|
|||||||
void attachSpectrumCanvas(SpectrumCanvas *canvas_in);
|
void attachSpectrumCanvas(SpectrumCanvas *canvas_in);
|
||||||
void processInputQueue();
|
void processInputQueue();
|
||||||
SpectrumVisualDataQueue *getVisualDataQueue();
|
SpectrumVisualDataQueue *getVisualDataQueue();
|
||||||
void DoPaint();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
|
Loading…
Reference in New Issue
Block a user