mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-04 08:21:16 -05:00
VisualProcessor now a template base, more tweaking needed
This commit is contained in:
parent
3fbb1def49
commit
61add8ae09
@ -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:
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
@ -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:
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user