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

View File

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

View File

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

View File

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

View File

@ -211,6 +211,15 @@ public:
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.
*/