diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 2942555..f2ec1e0 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -395,6 +395,7 @@ AppFrame::AppFrame() : waterfallSpeedMeter->setLevel(sqrt(wflps)); waterfallDataThread->setLinesPerSecond(wflps); + waterfallCanvas->setLinesPerSecond(wflps); ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme()); @@ -507,6 +508,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) { spectrumCanvas->setBandwidth(wxGetApp().getSampleRate()); spectrumCanvas->setCenterFrequency(wxGetApp().getFrequency()); waterfallDataThread->setLinesPerSecond(DEFAULT_WATERFALL_LPS); + waterfallCanvas->setLinesPerSecond(DEFAULT_WATERFALL_LPS); waterfallSpeedMeter->setLevel(sqrt(DEFAULT_WATERFALL_LPS)); wxGetApp().getSpectrumProcessor()->setFFTAverageRate(0.65); spectrumAvgMeter->setLevel(0.65); @@ -832,6 +834,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) { float val = waterfallSpeedMeter->getInputValue(); waterfallSpeedMeter->setLevel(val); waterfallDataThread->setLinesPerSecond((int)ceil(val*val)); + waterfallCanvas->setLinesPerSecond((int)ceil(val*val)); GetStatusBar()->SetStatusText(wxString::Format(wxT("Waterfall max speed changed to %d lines per second."),(int)ceil(val*val))); } diff --git a/src/IOThread.h b/src/IOThread.h index 743635c..ac3e36b 100644 --- a/src/IOThread.h +++ b/src/IOThread.h @@ -8,6 +8,7 @@ #include #include "ThreadQueue.h" +#include "Timer.h" struct map_string_less : public std::binary_function { @@ -112,9 +113,9 @@ public: void setOutputQueue(std::string qname, ThreadQueueBase *threadQueue); void *getOutputQueue(std::string qname); - protected: std::map input_queues; std::map output_queues; std::atomic_bool terminated; + Timer gTimer; }; diff --git a/src/process/FFTDataDistributor.cpp b/src/process/FFTDataDistributor.cpp index aecb0cc..2f78953 100644 --- a/src/process/FFTDataDistributor.cpp +++ b/src/process/FFTDataDistributor.cpp @@ -47,11 +47,11 @@ void FFTDataDistributor::process() { if (inputBuffer.data.size() >= fftSize) { int numProcessed = 0; -// if (lineRateAccum + (lineRateStep * floor((double)inputBuffer.data.size()/(double)fftSize)) < 1.0) { -// // move along, nothing to see here.. -// lineRateAccum += (lineRateStep * inputBuffer.data.size()/fftSize); -// numProcessed = inputBuffer.data.size()/fftSize; -// } else { + if (lineRateAccum + (lineRateStep * ((double)inputBuffer.data.size()/(double)fftSize)) < 1.0) { + // move along, nothing to see here.. + lineRateAccum += (lineRateStep * ((double)inputBuffer.data.size()/(double)fftSize)); + numProcessed = inputBuffer.data.size(); + } else { for (int i = 0, iMax = inputBuffer.data.size(); i < iMax; i += fftSize) { if ((i + fftSize) > iMax) { break; @@ -72,7 +72,7 @@ void FFTDataDistributor::process() { numProcessed += fftSize; } -// } + } if (numProcessed) { inputBuffer.data.erase(inputBuffer.data.begin(), inputBuffer.data.begin() + numProcessed); } diff --git a/src/util/Timer.cpp b/src/util/Timer.cpp index 99ca67a..b45812b 100644 --- a/src/util/Timer.cpp +++ b/src/util/Timer.cpp @@ -5,6 +5,8 @@ #include #endif +#include + Timer::Timer(void) : time_elapsed(0), system_milliseconds(0), start_time(0), end_time(0), last_update(0), num_updates(0), paused_time(0), offset(0), paused_state(false), lock_state(0), lock_rate(0) { } @@ -157,3 +159,14 @@ bool Timer::paused() { return paused_state; } + +void Timer::timerTestFunc() { + update(); + if (getNumUpdates() % 120 == 0) { + std::cout << getNumUpdates() << "," << getSeconds() << " Rate: " << ((double)getNumUpdates()/getSeconds()) << "/sec" << std::endl; + } + if (getNumUpdates() >= 600) { + reset(); + } +} + diff --git a/src/util/Timer.h b/src/util/Timer.h index 58589d6..554face 100644 --- a/src/util/Timer.h +++ b/src/util/Timer.h @@ -155,6 +155,9 @@ public: * \return Current pause state, true if paused, false otherwise */ bool paused(); + + + void timerTestFunc(); }; #endif diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index bfd1bc6..1ae983f 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -39,7 +39,9 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : dragOfs(0), mouseZoom(1), zoom(1), freqMove(0.0), freqMoving(false), hoverAlpha(1.0) { glContext = new PrimaryGLContext(this, &wxGetApp().GetContext(this)); - + linesPerSecond = 30; + lpsIndex = 0; + preBuf = false; SetCursor(wxCURSOR_CROSS); } @@ -54,6 +56,8 @@ void WaterfallCanvas::setup(int fft_size_in, int waterfall_lines_in) { waterfall_lines = waterfall_lines_in; waterfallPanel.setup(fft_size, waterfall_lines); + gTimer.start(); + testTimer.start(); } WaterfallCanvas::DragState WaterfallCanvas::getDragState() { @@ -75,25 +79,47 @@ void WaterfallCanvas::processInputQueue() { glContext->SetCurrent(*this); bool processed = false; - int numVis = visualDataQueue.size(); - for (int i = 0; i < numVis; i++) { - SpectrumVisualData *vData; - visualDataQueue.pop(vData); - - if (vData) { - waterfallPanel.setPoints(vData->spectrum_points); - waterfallPanel.step(); - vData->decRefCount(); - processed = true; +// int numVis = visualDataQueue.size(); + + gTimer.update(); +// if (visualDataQueue.size() < 10 && !preBuf) { +// return; +// } else { +// preBuf = true; +// if (visualDataQueue.size() < 2) { +// preBuf = false; +// } +// } +// + double targetVis = 1.0 / (double)linesPerSecond; + lpsIndex += gTimer.lastUpdateSeconds(); + + if (linesPerSecond) { + if (lpsIndex >= targetVis) { + while (lpsIndex >= targetVis) { + SpectrumVisualData *vData; + if (!visualDataQueue.empty()) { + visualDataQueue.pop(vData); + + if (vData) { + waterfallPanel.setPoints(vData->spectrum_points); + waterfallPanel.step(); + vData->decRefCount(); + processed = true; + } + } + lpsIndex-=targetVis; + } } } if (processed) { - Refresh(); +// Refresh(); } } void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { // wxClientDC dc(this); + testTimer.timerTestFunc(); wxPaintDC dc(this); //#ifdef __APPLE__ @@ -401,11 +427,11 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { } void WaterfallCanvas::OnIdle(wxIdleEvent &event) { -// Refresh(); + Refresh(); // processInputQueue(); // Refresh(); -// event.RequestMore(); - event.Skip(); + event.RequestMore(); +// event.Skip(); } void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { @@ -793,3 +819,8 @@ void WaterfallCanvas::updateCenterFrequency(long long freq) { } +void WaterfallCanvas::setLinesPerSecond(int lps) { + linesPerSecond = lps; +} + + diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 28d0070..7887618 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -10,7 +10,7 @@ #include "MouseTracker.h" #include "SpectrumCanvas.h" #include "WaterfallPanel.h" - +#include "Timer.h" class WaterfallCanvas: public InteractiveCanvas { public: @@ -29,6 +29,8 @@ public: void processInputQueue(); SpectrumVisualDataQueue *getVisualDataQueue(); + void setLinesPerSecond(int lps); + private: void OnPaint(wxPaintEvent& event); void OnKeyDown(wxKeyEvent& event); @@ -64,9 +66,12 @@ private: bool freqMoving; long double freqMove; float hoverAlpha; - + int linesPerSecond; + SpectrumVisualDataQueue visualDataQueue; - + Timer gTimer, testTimer; + double lpsIndex; + bool preBuf; // event table wxDECLARE_EVENT_TABLE(); };