mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-29 15:18:38 -05:00
initial ScopeVisualProcessor, ReBuffer template
This commit is contained in:
parent
52e6de5f9d
commit
f731602017
@ -258,6 +258,7 @@ SET (cubicsdr_sources
|
|||||||
src/visual/WaterfallCanvas.cpp
|
src/visual/WaterfallCanvas.cpp
|
||||||
src/visual/WaterfallContext.cpp
|
src/visual/WaterfallContext.cpp
|
||||||
src/process/VisualProcessor.cpp
|
src/process/VisualProcessor.cpp
|
||||||
|
src/process/ScopeVisualProcessor.cpp
|
||||||
src/process/SpectrumVisualProcessor.cpp
|
src/process/SpectrumVisualProcessor.cpp
|
||||||
src/process/WaterfallVisualProcessor.cpp
|
src/process/WaterfallVisualProcessor.cpp
|
||||||
src/ui/GLPanel.cpp
|
src/ui/GLPanel.cpp
|
||||||
@ -308,6 +309,7 @@ SET (cubicsdr_headers
|
|||||||
src/visual/WaterfallCanvas.h
|
src/visual/WaterfallCanvas.h
|
||||||
src/visual/WaterfallContext.h
|
src/visual/WaterfallContext.h
|
||||||
src/process/VisualProcessor.h
|
src/process/VisualProcessor.h
|
||||||
|
src/process/ScopeVisualProcessor.h
|
||||||
src/process/SpectrumVisualProcessor.h
|
src/process/SpectrumVisualProcessor.h
|
||||||
src/process/WaterfallVisualProcessor.h
|
src/process/WaterfallVisualProcessor.h
|
||||||
src/ui/GLPanel.h
|
src/ui/GLPanel.h
|
||||||
|
@ -35,6 +35,7 @@ const char filePathSeparator =
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
class ReferenceCounter {
|
class ReferenceCounter {
|
||||||
public:
|
public:
|
||||||
@ -54,3 +55,33 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
std::atomic_int refCount;
|
std::atomic_int refCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class BufferType = ReferenceCounter>
|
||||||
|
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<BufferType*> outputBuffers;
|
||||||
|
typename std::deque<BufferType*>::iterator outputBuffersI;
|
||||||
|
};
|
||||||
|
@ -307,17 +307,7 @@ void DemodulatorThread::threadMain() {
|
|||||||
if (audioOutputQueue != NULL) {
|
if (audioOutputQueue != NULL) {
|
||||||
if (!squelchEnabled || (signalLevel >= squelchLevel)) {
|
if (!squelchEnabled || (signalLevel >= squelchLevel)) {
|
||||||
|
|
||||||
for (outputBuffersI = outputBuffers.begin(); outputBuffersI != outputBuffers.end(); outputBuffersI++) {
|
ati = outputBuffers.getBuffer();
|
||||||
if ((*outputBuffersI)->getRefCount() <= 0) {
|
|
||||||
ati = (*outputBuffersI);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ati == NULL) {
|
|
||||||
ati = new AudioThreadInput;
|
|
||||||
outputBuffers.push_back(ati);
|
|
||||||
}
|
|
||||||
|
|
||||||
ati->sampleRate = audioSampleRate;
|
ati->sampleRate = audioSampleRate;
|
||||||
ati->setRefCount(1);
|
ati->setRefCount(1);
|
||||||
@ -491,11 +481,7 @@ void DemodulatorThread::threadMain() {
|
|||||||
nco_crcf_destroy(stereoPilot);
|
nco_crcf_destroy(stereoPilot);
|
||||||
resamp2_cccf_destroy(ssbFilt);
|
resamp2_cccf_destroy(ssbFilt);
|
||||||
|
|
||||||
while (!outputBuffers.empty()) {
|
outputBuffers.purge();
|
||||||
AudioThreadInput *audioDataDel = outputBuffers.front();
|
|
||||||
outputBuffers.pop_front();
|
|
||||||
delete audioDataDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audioVisOutputQueue && !audioVisOutputQueue->empty()) {
|
if (audioVisOutputQueue && !audioVisOutputQueue->empty()) {
|
||||||
AudioThreadInput *dummy_vis;
|
AudioThreadInput *dummy_vis;
|
||||||
|
@ -48,8 +48,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::deque<AudioThreadInput *> outputBuffers;
|
ReBuffer<AudioThreadInput> outputBuffers;
|
||||||
std::deque<AudioThreadInput *>::iterator outputBuffersI;
|
|
||||||
|
|
||||||
std::vector<liquid_float_complex> agcData;
|
std::vector<liquid_float_complex> agcData;
|
||||||
std::vector<float> agcAMData;
|
std::vector<float> agcAMData;
|
||||||
|
1
src/process/ScopeVisualProcessor.cpp
Normal file
1
src/process/ScopeVisualProcessor.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "ScopeVisualProcessor.h"
|
63
src/process/ScopeVisualProcessor.h
Normal file
63
src/process/ScopeVisualProcessor.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "VisualProcessor.h"
|
||||||
|
#include "AudioThread.h"
|
||||||
|
|
||||||
|
class ScopeVisualProcessor : public VisualProcessor {
|
||||||
|
protected:
|
||||||
|
std::vector<float> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
};
|
@ -94,8 +94,7 @@ void SDRPostThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "SDR post-processing thread started.." << std::endl;
|
std::cout << "SDR post-processing thread started.." << std::endl;
|
||||||
|
|
||||||
std::deque<DemodulatorThreadIQData *> buffers;
|
ReBuffer<DemodulatorThreadIQData> buffers;
|
||||||
std::deque<DemodulatorThreadIQData *>::iterator buffers_i;
|
|
||||||
std::vector<liquid_float_complex> fpData;
|
std::vector<liquid_float_complex> fpData;
|
||||||
std::vector<liquid_float_complex> dataOut;
|
std::vector<liquid_float_complex> dataOut;
|
||||||
|
|
||||||
@ -176,19 +175,7 @@ void SDRPostThread::threadMain() {
|
|||||||
|
|
||||||
if (demodulators.size()) {
|
if (demodulators.size()) {
|
||||||
|
|
||||||
DemodulatorThreadIQData *demodDataOut = NULL;
|
DemodulatorThreadIQData *demodDataOut = buffers.getBuffer();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
|
// std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
|
||||||
demodDataOut->frequency = data_in->frequency;
|
demodDataOut->frequency = data_in->frequency;
|
||||||
@ -242,12 +229,8 @@ void SDRPostThread::threadMain() {
|
|||||||
data_in->decRefCount();
|
data_in->decRefCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!buffers.empty()) {
|
// buffers.purge();
|
||||||
DemodulatorThreadIQData *demodDataDel = buffers.front();
|
|
||||||
buffers.pop_front();
|
|
||||||
// std::lock_guard < std::mutex > lock(demodDataDel->m_mutex);
|
|
||||||
// delete demodDataDel;
|
|
||||||
}
|
|
||||||
if (iqVisualQueue.load() && !iqVisualQueue.load()->empty()) {
|
if (iqVisualQueue.load() && !iqVisualQueue.load()->empty()) {
|
||||||
DemodulatorThreadIQData *visualDataDummy;
|
DemodulatorThreadIQData *visualDataDummy;
|
||||||
iqVisualQueue.load()->pop(visualDataDummy);
|
iqVisualQueue.load()->pop(visualDataDummy);
|
||||||
|
@ -168,8 +168,7 @@ void SDRThread::threadMain() {
|
|||||||
|
|
||||||
std::cout << "SDR thread started.." << std::endl;
|
std::cout << "SDR thread started.." << std::endl;
|
||||||
|
|
||||||
std::deque<SDRThreadIQData *> buffers;
|
ReBuffer<SDRThreadIQData> buffers;
|
||||||
std::deque<SDRThreadIQData *>::iterator buffers_i;
|
|
||||||
|
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
SDRThreadCommandQueue *cmdQueue = commandQueue.load();
|
SDRThreadCommandQueue *cmdQueue = commandQueue.load();
|
||||||
@ -274,19 +273,7 @@ void SDRThread::threadMain() {
|
|||||||
|
|
||||||
rtlsdr_read_sync(dev, buf, buf_size, &n_read);
|
rtlsdr_read_sync(dev, buf, buf_size, &n_read);
|
||||||
|
|
||||||
SDRThreadIQData *dataOut = NULL;
|
SDRThreadIQData *dataOut = buffers.getBuffer();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::lock_guard < std::mutex > lock(dataOut->m_mutex);
|
// std::lock_guard < std::mutex > lock(dataOut->m_mutex);
|
||||||
dataOut->setRefCount(1);
|
dataOut->setRefCount(1);
|
||||||
@ -311,12 +298,7 @@ void SDRThread::threadMain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!buffers.empty()) {
|
// buffers.purge();
|
||||||
SDRThreadIQData *iqDataDel = buffers.front();
|
|
||||||
buffers.pop_front();
|
|
||||||
// std::lock_guard < std::mutex > lock(iqDataDel->m_mutex);
|
|
||||||
// delete iqDataDel;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "SDR thread done." << std::endl;
|
std::cout << "SDR thread done." << std::endl;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user