mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-02-03 09:44:26 -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 "VisualProcessor.h"
|
||||||
#include "AudioThread.h"
|
#include "AudioThread.h"
|
||||||
|
|
||||||
class ScopeVisualProcessor : public VisualProcessor {
|
class ScopeRenderData: public ReferenceCounter {
|
||||||
protected:
|
public:
|
||||||
std::vector<float> waveform_points;
|
std::vector<float> waveform_points;
|
||||||
|
int channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef ThreadQueue<ScopeRenderData *> ScopeRenderDataQueue;
|
||||||
|
|
||||||
|
class ScopeVisualProcessor : public VisualProcessor<AudioThreadInputQueue, ScopeRenderDataQueue, ScopeRenderData> {
|
||||||
|
protected:
|
||||||
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:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
};
|
|
@ -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() {
|
||||||
/*
|
/*
|
||||||
@ -82,4 +87,4 @@ protected:
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
/*
|
/*
|
||||||
@ -278,4 +282,4 @@ protected:
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user