diff --git a/CMakeLists.txt b/CMakeLists.txt index 92cfe0a..5c164f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -258,6 +258,7 @@ SET (cubicsdr_sources src/visual/WaterfallCanvas.cpp src/visual/WaterfallContext.cpp src/process/VisualProcessor.cpp + src/process/ScopeVisualProcessor.cpp src/process/SpectrumVisualProcessor.cpp src/process/WaterfallVisualProcessor.cpp src/ui/GLPanel.cpp @@ -308,6 +309,7 @@ SET (cubicsdr_headers src/visual/WaterfallCanvas.h src/visual/WaterfallContext.h src/process/VisualProcessor.h + src/process/ScopeVisualProcessor.h src/process/SpectrumVisualProcessor.h src/process/WaterfallVisualProcessor.h src/ui/GLPanel.h diff --git a/src/CubicSDRDefs.h b/src/CubicSDRDefs.h index 2b6de43..ae8ca66 100644 --- a/src/CubicSDRDefs.h +++ b/src/CubicSDRDefs.h @@ -35,6 +35,7 @@ const char filePathSeparator = #include #include +#include class ReferenceCounter { public: @@ -54,3 +55,33 @@ public: protected: std::atomic_int refCount; }; + +template +class ReBuffer { + +public: + BufferType *getBuffer() { + BufferType* buf = NULL; + for (outputBuffersI = outputBuffers.begin(); outputBuffersI != outputBuffers.end(); outputBuffersI++) { + if ((*outputBuffersI)->getRefCount() <= 0) { + return (*outputBuffersI); + } + } + + buf = new BufferType(); + outputBuffers.push_back(buf); + + return buf; + } + + void purge() { + while (!outputBuffers.empty()) { + BufferType *ref = outputBuffers.front(); + outputBuffers.pop_front(); + delete ref; + } + } +private: + std::deque outputBuffers; + typename std::deque::iterator outputBuffersI; +}; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 86ce709..0194adb 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -307,17 +307,7 @@ void DemodulatorThread::threadMain() { if (audioOutputQueue != NULL) { if (!squelchEnabled || (signalLevel >= squelchLevel)) { - for (outputBuffersI = outputBuffers.begin(); outputBuffersI != outputBuffers.end(); outputBuffersI++) { - if ((*outputBuffersI)->getRefCount() <= 0) { - ati = (*outputBuffersI); - break; - } - } - - if (ati == NULL) { - ati = new AudioThreadInput; - outputBuffers.push_back(ati); - } + ati = outputBuffers.getBuffer(); ati->sampleRate = audioSampleRate; ati->setRefCount(1); @@ -491,11 +481,7 @@ void DemodulatorThread::threadMain() { nco_crcf_destroy(stereoPilot); resamp2_cccf_destroy(ssbFilt); - while (!outputBuffers.empty()) { - AudioThreadInput *audioDataDel = outputBuffers.front(); - outputBuffers.pop_front(); - delete audioDataDel; - } + outputBuffers.purge(); if (audioVisOutputQueue && !audioVisOutputQueue->empty()) { AudioThreadInput *dummy_vis; diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index be6cf69..bad7050 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -48,8 +48,7 @@ public: #endif protected: - std::deque outputBuffers; - std::deque::iterator outputBuffersI; + ReBuffer outputBuffers; std::vector agcData; std::vector agcAMData; diff --git a/src/process/ScopeVisualProcessor.cpp b/src/process/ScopeVisualProcessor.cpp new file mode 100644 index 0000000..89af21c --- /dev/null +++ b/src/process/ScopeVisualProcessor.cpp @@ -0,0 +1 @@ +#include "ScopeVisualProcessor.h" \ No newline at end of file diff --git a/src/process/ScopeVisualProcessor.h b/src/process/ScopeVisualProcessor.h new file mode 100644 index 0000000..e5dd56c --- /dev/null +++ b/src/process/ScopeVisualProcessor.h @@ -0,0 +1,63 @@ +#pragma once + +#include "VisualProcessor.h" +#include "AudioThread.h" + +class ScopeVisualProcessor : public VisualProcessor { +protected: + std::vector waveform_points; + + virtual void process() { + if (!input->empty()) { + ReferenceCounter *ati_ref; + input->pop(ati_ref); + + AudioThreadInput *ati = (AudioThreadInput *)ati_ref; + if (!ati) { + return; + } + int iMax = ati->data.size(); + if (!iMax) { + ati->decRefCount(); + return; + } + if (waveform_points.size() != iMax * 2) { + waveform_points.resize(iMax * 2); + } + + for (int i = 0; i < iMax; i++) { + waveform_points[i * 2 + 1] = ati->data[i] * 0.5f; + waveform_points[i * 2] = ((double) i / (double) iMax); + } + + // ati->channels + } +/* + if (!wxGetApp().getAudioVisualQueue()->empty()) { + AudioThreadInput *demodAudioData; + wxGetApp().getAudioVisualQueue()->pop(demodAudioData); + + 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; + } + } +*/ + } +}; \ No newline at end of file diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 5a22aab..66d9c1a 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -94,8 +94,7 @@ void SDRPostThread::threadMain() { std::cout << "SDR post-processing thread started.." << std::endl; - std::deque buffers; - std::deque::iterator buffers_i; + ReBuffer buffers; std::vector fpData; std::vector dataOut; @@ -176,19 +175,7 @@ void SDRPostThread::threadMain() { if (demodulators.size()) { - DemodulatorThreadIQData *demodDataOut = NULL; - - for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { - if ((*buffers_i)->getRefCount() <= 0) { - demodDataOut = (*buffers_i); - break; - } - } - - if (demodDataOut == NULL) { - demodDataOut = new DemodulatorThreadIQData; - buffers.push_back(demodDataOut); - } + DemodulatorThreadIQData *demodDataOut = buffers.getBuffer(); // std::lock_guard < std::mutex > lock(demodDataOut->m_mutex); demodDataOut->frequency = data_in->frequency; @@ -242,12 +229,8 @@ void SDRPostThread::threadMain() { data_in->decRefCount(); } - while (!buffers.empty()) { - DemodulatorThreadIQData *demodDataDel = buffers.front(); - buffers.pop_front(); -// std::lock_guard < std::mutex > lock(demodDataDel->m_mutex); -// delete demodDataDel; - } +// buffers.purge(); + if (iqVisualQueue.load() && !iqVisualQueue.load()->empty()) { DemodulatorThreadIQData *visualDataDummy; iqVisualQueue.load()->pop(visualDataDummy); diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index 6f1a66e..88635f1 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -168,8 +168,7 @@ void SDRThread::threadMain() { std::cout << "SDR thread started.." << std::endl; - std::deque buffers; - std::deque::iterator buffers_i; + ReBuffer buffers; while (!terminated) { SDRThreadCommandQueue *cmdQueue = commandQueue.load(); @@ -274,19 +273,7 @@ void SDRThread::threadMain() { rtlsdr_read_sync(dev, buf, buf_size, &n_read); - SDRThreadIQData *dataOut = NULL; - - for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { - if ((*buffers_i)->getRefCount() <= 0) { - dataOut = (*buffers_i); - break; - } - } - - if (dataOut == NULL) { - dataOut = new SDRThreadIQData; - buffers.push_back(dataOut); - } + SDRThreadIQData *dataOut = buffers.getBuffer(); // std::lock_guard < std::mutex > lock(dataOut->m_mutex); dataOut->setRefCount(1); @@ -311,13 +298,8 @@ void SDRThread::threadMain() { } } - while (!buffers.empty()) { - SDRThreadIQData *iqDataDel = buffers.front(); - buffers.pop_front(); -// std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); -// delete iqDataDel; - } - + // buffers.purge(); + std::cout << "SDR thread done." << std::endl; }