VisualProcessor now a template base, more tweaking needed

This commit is contained in:
Charles J. Cliffe 2015-07-31 21:03:17 -04:00
parent 3fbb1def49
commit 61add8ae09
5 changed files with 99 additions and 37 deletions

View File

@ -3,35 +3,54 @@
#include "VisualProcessor.h" #include "VisualProcessor.h"
#include "AudioThread.h" #include "AudioThread.h"
class ScopeVisualProcessor : public VisualProcessor { class ScopeRenderData: public ReferenceCounter {
public:
std::vector<float> waveform_points;
int channels;
};
typedef ThreadQueue<ScopeRenderData *> ScopeRenderDataQueue;
class ScopeVisualProcessor : public VisualProcessor<AudioThreadInputQueue, ScopeRenderDataQueue, ScopeRenderData> {
protected: protected:
std::vector<float> waveform_points;
virtual void process() { virtual void process() {
if (isOutputEmpty()) {
return;
}
if (!input->empty()) { if (!input->empty()) {
ReferenceCounter *ati_ref; AudioThreadInput *audioInputData;
input->pop(ati_ref); input->pop(audioInputData);
AudioThreadInput *ati = (AudioThreadInput *)ati_ref; if (!audioInputData) {
if (!ati) {
return; return;
} }
int iMax = ati->data.size(); int iMax = audioInputData->data.size();
if (!iMax) { if (!iMax) {
ati->decRefCount(); audioInputData->decRefCount();
return; return;
} }
if (waveform_points.size() != iMax * 2) {
waveform_points.resize(iMax * 2); ScopeRenderData *renderData = outputBuffers.getBuffer();
renderData->channels = audioInputData->channels;
if (renderData->waveform_points.size() != iMax * 2) {
renderData->waveform_points.resize(iMax * 2);
} }
for (int i = 0; i < iMax; i++) { for (int i = 0; i < iMax; i++) {
waveform_points[i * 2 + 1] = ati->data[i] * 0.5f; renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] * 0.5f;
waveform_points[i * 2] = ((double) i / (double) iMax); renderData->waveform_points[i * 2] = ((double) i / (double) iMax);
} }
distribute(renderData);
// ati->channels // ati->channels
} }
}
ReBuffer<ScopeRenderData> outputBuffers;
};
/* /*
if (!wxGetApp().getAudioVisualQueue()->empty()) { if (!wxGetApp().getAudioVisualQueue()->empty()) {
AudioThreadInput *demodAudioData; AudioThreadInput *demodAudioData;
@ -59,5 +78,3 @@ protected:
} }
} }
*/ */
}
};

View File

@ -1,8 +1,13 @@
#pragma once #pragma once
#include "VisualProcessor.h" #include "VisualProcessor.h"
#include "SpectrumCanvas.h"
class SpectrumVisualProcessor : public VisualProcessor { class SpectrumVisualData : public ReferenceCounter {
};
class SpectrumVisualProcessor : public VisualProcessor<DemodulatorThreadIQData, SpectrumVisualData> {
protected: protected:
virtual void process() { virtual void process() {
/* /*

View File

@ -5,27 +5,30 @@
#include "IOThread.h" #include "IOThread.h"
#include <algorithm> #include <algorithm>
typedef ThreadQueue<ReferenceCounter *> VisualDataQueue; template<class InputQueueType = ThreadQueueBase, class OutputQueueType = ThreadQueueBase, class OutputDataType = ReferenceCounter>
class VisualProcessor { class VisualProcessor {
public: public:
void setInput(VisualDataQueue *vis_in) { virtual ~VisualProcessor() {
}
void setInput(InputQueueType *vis_in) {
busy_update.lock(); busy_update.lock();
input = vis_in; input = vis_in;
busy_update.unlock(); busy_update.unlock();
} }
void attachOutput(VisualDataQueue *vis_out) { void attachOutput(OutputQueueType *vis_out) {
// attach an output queue // attach an output queue
busy_update.lock(); busy_update.lock();
outputs.push_back(vis_out); outputs.push_back(vis_out);
busy_update.unlock(); busy_update.unlock();
} }
void removeOutput(VisualDataQueue *vis_out) { void removeOutput(OutputQueueType *vis_out) {
// remove an output queue // remove an output queue
busy_update.lock(); busy_update.lock();
std::vector<VisualDataQueue *>::iterator i = std::find(outputs.begin(), outputs.end(), vis_out); typename std::vector<OutputQueueType *>::iterator i = std::find(outputs.begin(), outputs.end(), vis_out);
if (i != outputs.end()) { if (i != outputs.end()) {
outputs.erase(i); outputs.erase(i);
} }
@ -46,29 +49,53 @@ protected:
// distribute(output); // distribute(output);
} }
void distribute(ReferenceCounter *output) { void distribute(OutputDataType *output) {
// distribute outputs // distribute outputs
output->setRefCount(outputs.size()); output->setRefCount(outputs.size());
std::vector<VisualDataQueue *>::iterator outputs_i;
for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) {
(*outputs_i)->push(output); if ((*outputs_i)->full()) {
output->decRefCount();
} else {
(*outputs_i)->push(output);
}
} }
} }
VisualDataQueue * input; bool isOutputEmpty() {
std::vector<VisualDataQueue *> outputs; for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) {
if (!(*outputs_i)->empty()) {
return false;
}
}
return true;
}
bool isAnyOutputEmpty() {
for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) {
if ((*outputs_i)->empty()) {
return true;
}
}
return false;
}
InputQueueType *input;
std::vector<OutputQueueType *> outputs;
typename std::vector<OutputQueueType *>::iterator outputs_i;
std::mutex busy_update; std::mutex busy_update;
}; };
class VisualDataDistributor : public VisualProcessor { template<class QueueType = ThreadQueueBase, class OutputDataType = ReferenceCounter>
class VisualDataDistributor : public VisualProcessor<QueueType, QueueType, OutputDataType> {
protected: protected:
virtual void process() { void process() {
while (!input->empty()) {
ReferenceCounter *inp; while (!VisualProcessor<QueueType, QueueType, OutputDataType>::input->empty()) {
input->pop(inp); ReferenceCounter *inp;
VisualProcessor<QueueType, QueueType, OutputDataType>::input->pop(inp);
if (inp) { if (inp) {
distribute(inp); VisualProcessor<QueueType, QueueType, OutputDataType>::distribute(inp);
} }
} }
} }

View File

@ -1,9 +1,13 @@
#pragma once #pragma once
#include "VisualProcessor.h" #include "VisualProcessor.h"
#include "WaterfallCanvas.h"
class WaterfallVisualData : public ReferenceCounter {
class WaterfallVisualProcessor : public VisualProcessor { };
class WaterfallVisualProcessor : public VisualProcessor<DemodulatorThreadIQData, WaterfallVisualData> {
protected: protected:
virtual void process() { virtual void process() {
/* /*

View File

@ -211,6 +211,15 @@ public:
return m_queue.empty(); return m_queue.empty();
} }
/**
* Check if the queue is empty.
* \return true if queue is empty.
*/
bool full() const {
std::lock_guard < std::mutex > lock(m_mutex);
return m_queue.size() >= m_max_num_items;
}
/** /**
* Remove any items in the queue. * Remove any items in the queue.
*/ */