Changed data transaction objects to use pointers

This commit is contained in:
Charles J. Cliffe 2014-12-22 19:43:56 -05:00
parent 24c86bc9e4
commit 312b25f55a
11 changed files with 125 additions and 56 deletions

View File

@ -99,9 +99,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
SDRThreadIQData iqData; SDRThreadIQData iqData;
wxGetApp().getIQVisualQueue()->pop(iqData); wxGetApp().getIQVisualQueue()->pop(iqData);
if (iqData.data.size()) { if (iqData.data && iqData.data->size()) {
spectrumCanvas->setData(&iqData.data); spectrumCanvas->setData(iqData.data);
waterfallCanvas->setData(&iqData.data); waterfallCanvas->setData(iqData.data);
delete iqData.data;
} else { } else {
std::cout << "Incoming IQ data empty?" << std::endl; std::cout << "Incoming IQ data empty?" << std::endl;
} }
@ -111,17 +113,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
if (!wxGetApp().getAudioVisualQueue()->empty()) { if (!wxGetApp().getAudioVisualQueue()->empty()) {
AudioThreadInput demodAudioData; AudioThreadInput demodAudioData;
wxGetApp().getAudioVisualQueue()->pop(demodAudioData); wxGetApp().getAudioVisualQueue()->pop(demodAudioData);
if (demodAudioData.data.size()) { if (demodAudioData.data && demodAudioData.data->size()) {
if (scopeCanvas->waveform_points.size() != demodAudioData.data.size()*2) { if (scopeCanvas->waveform_points.size() != demodAudioData.data->size()*2) {
scopeCanvas->waveform_points.resize(demodAudioData.data.size()*2); scopeCanvas->waveform_points.resize(demodAudioData.data->size()*2);
} }
for (int i = 0, iMax = demodAudioData.data.size(); i < iMax; i++) { for (int i = 0, iMax = demodAudioData.data->size(); i < iMax; i++) {
scopeCanvas->waveform_points[i * 2 + 1] = demodAudioData.data[i] * 0.5f; scopeCanvas->waveform_points[i * 2 + 1] = (*demodAudioData.data)[i] * 0.5f;
scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax); scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax);
} }
delete demodAudioData.data;
} else { } else {
std::cout << "Incoming Demodulator data empty?" << std::endl; std::cout << "Incoming Demodulator data empty?" << std::endl;
} }

View File

@ -65,7 +65,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
continue; continue;
} }
if (srcmix->currentInput.channels == 0) { if (srcmix->currentInput.channels == 0 || !srcmix->currentInput.data) {
if (!srcmix->inputQueue->empty()) { if (!srcmix->inputQueue->empty()) {
srcmix->inputQueue->pop(srcmix->currentInput); srcmix->inputQueue->pop(srcmix->currentInput);
} }
@ -110,8 +110,11 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl; std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl;
} }
if (src->currentInput.channels == 0) { if (src->currentInput.channels == 0 || !src->currentInput.data) {
if (!src->inputQueue->empty()) { if (!src->inputQueue->empty()) {
if (src->currentInput.data) {
delete src->currentInput.data;
}
src->inputQueue->pop(src->currentInput); src->inputQueue->pop(src->currentInput);
} }
return 0; return 0;
@ -119,26 +122,29 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
if (src->currentInput.channels == 1) { if (src->currentInput.channels == 1) {
for (int i = 0; i < nBufferFrames; i++) { for (int i = 0; i < nBufferFrames; i++) {
if (src->audio_queue_ptr >= src->currentInput.data.size()) { if (src->audio_queue_ptr >= src->currentInput.data->size()) {
if (src->currentInput.data) {
delete src->currentInput.data;
}
if (src->terminated) { if (src->terminated) {
break; break;
} }
src->inputQueue->pop(src->currentInput); src->inputQueue->pop(src->currentInput);
src->audio_queue_ptr = 0; src->audio_queue_ptr = 0;
} }
out[i * 2] = out[i * 2 + 1] = src->currentInput.data[src->audio_queue_ptr] * src->gain; out[i * 2] = out[i * 2 + 1] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain;
src->audio_queue_ptr++; src->audio_queue_ptr++;
} }
} else { } else {
for (int i = 0, iMax = src->currentInput.channels * nBufferFrames; i < iMax; i++) { for (int i = 0, iMax = src->currentInput.channels * nBufferFrames; i < iMax; i++) {
if (src->audio_queue_ptr >= src->currentInput.data.size()) { if (src->audio_queue_ptr >= src->currentInput.data->size()) {
if (src->terminated) { if (src->terminated) {
break; break;
} }
src->inputQueue->pop(src->currentInput); src->inputQueue->pop(src->currentInput);
src->audio_queue_ptr = 0; src->audio_queue_ptr = 0;
} }
out[i] = src->currentInput.data[src->audio_queue_ptr] * src->gain; out[i] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain;
src->audio_queue_ptr++; src->audio_queue_ptr++;
} }
} }
@ -302,11 +308,17 @@ void AudioThread::setActive(bool state) {
deviceController[parameters.deviceId]->bindThread(this); deviceController[parameters.deviceId]->bindThread(this);
while (!inputQueue->empty()) { // flush queue while (!inputQueue->empty()) { // flush queue
inputQueue->pop(dummy); inputQueue->pop(dummy);
if (dummy.data) {
delete dummy.data;
}
} }
} else if (!state && active) { } else if (!state && active) {
deviceController[parameters.deviceId]->removeThread(this); deviceController[parameters.deviceId]->removeThread(this);
while (!inputQueue->empty()) { // flush queue while (!inputQueue->empty()) { // flush queue
inputQueue->pop(dummy); inputQueue->pop(dummy);
if (dummy.data) {
delete dummy.data;
}
} }
} }
#endif #endif

View File

@ -24,7 +24,7 @@ public:
int sampleRate; int sampleRate;
int channels; int channels;
AudioThreadInput(): frequency(0), sampleRate(0), channels(0) { AudioThreadInput(): frequency(0), sampleRate(0), channels(0), data(NULL) {
} }
@ -32,7 +32,7 @@ public:
} }
std::vector<float> data; std::vector<float> *data;
}; };
class AudioThreadCommand { class AudioThreadCommand {

View File

@ -4,6 +4,8 @@
#include "CubicSDRDefs.h" #include "CubicSDRDefs.h"
#include "liquid/liquid.h" #include "liquid/liquid.h"
#include <atomic>
enum DemodulatorType { enum DemodulatorType {
DEMOD_TYPE_NULL, DEMOD_TYPE_NULL,
DEMOD_TYPE_AM, DEMOD_TYPE_AM,
@ -57,17 +59,35 @@ class DemodulatorThreadIQData {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int bandwidth; unsigned int bandwidth;
std::vector<signed char> data; std::vector<signed char> *data;
std::atomic<int> *refCount;
DemodulatorThreadIQData() : DemodulatorThreadIQData() :
frequency(0), bandwidth(0) { frequency(0), bandwidth(0), data(NULL), refCount(0) {
} }
DemodulatorThreadIQData(unsigned int bandwidth, unsigned int frequency, DemodulatorThreadIQData(const DemodulatorThreadIQData& o) {
std::vector<signed char> data) : frequency = o.frequency;
data(data), frequency(frequency), bandwidth(bandwidth) { bandwidth = o.bandwidth;
data = o.data;
refCount = o.refCount;
}
void setRefCount(std::atomic<int> *rc) {
refCount = rc;
}
void cleanup() {
if (refCount) {
(*refCount)--;
if ((*refCount) <= 0) {
delete data;
data = NULL;
delete refCount;
refCount = NULL;
}
}
} }
~DemodulatorThreadIQData() { ~DemodulatorThreadIQData() {
@ -77,16 +97,24 @@ public:
class DemodulatorThreadPostIQData { class DemodulatorThreadPostIQData {
public: public:
std::vector<liquid_float_complex> data; std::vector<liquid_float_complex> *data;
float audio_resample_ratio; float audio_resample_ratio;
msresamp_rrrf audio_resampler; msresamp_rrrf audio_resampler;
float resample_ratio; float resample_ratio;
msresamp_crcf resampler; msresamp_crcf resampler;
DemodulatorThreadPostIQData(): audio_resample_ratio(0), audio_resampler(NULL), resample_ratio(0), resampler(NULL) { DemodulatorThreadPostIQData(): audio_resample_ratio(0), audio_resampler(NULL), resample_ratio(0), resampler(NULL), data(NULL) {
} }
DemodulatorThreadPostIQData(const DemodulatorThreadPostIQData &o) {
audio_resample_ratio = o.audio_resample_ratio;
audio_resampler = o.audio_resampler;
resample_ratio = o.resample_ratio;
resampler = o.resampler;
data = o.data;
}
~DemodulatorThreadPostIQData() { ~DemodulatorThreadPostIQData() {
} }
@ -99,15 +127,15 @@ public:
unsigned int sampleRate; unsigned int sampleRate;
unsigned char channels; unsigned char channels;
std::vector<float> data; std::vector<float> *data;
DemodulatorThreadAudioData() : DemodulatorThreadAudioData() :
sampleRate(0), frequency(0), channels(0) { sampleRate(0), frequency(0), channels(0), data(NULL) {
} }
DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate,
std::vector<float> data) : std::vector<float> *data) :
data(data), sampleRate(sampleRate), frequency(frequency), channels( data(data), sampleRate(sampleRate), frequency(frequency), channels(
1) { 1) {

View File

@ -157,8 +157,8 @@ void DemodulatorPreThread::threadMain() {
continue; continue;
} }
std::vector<signed char> *data = &inp.data; std::vector<signed char> *data = inp.data;
if (data->size()) { if (data && data->size()) {
int bufSize = data->size() / 2; int bufSize = data->size() / 2;
liquid_float_complex in_buf_data[bufSize]; liquid_float_complex in_buf_data[bufSize];
@ -185,9 +185,10 @@ void DemodulatorPreThread::threadMain() {
} }
DemodulatorThreadPostIQData resamp; DemodulatorThreadPostIQData resamp;
resamp.data.resize(bufSize); resamp.data = new std::vector<liquid_float_complex>;
resamp.data->resize(bufSize);
firfilt_crcf_execute_block(fir_filter, in_buf, bufSize, &resamp.data[0]); firfilt_crcf_execute_block(fir_filter, in_buf, bufSize, &((*resamp.data)[0]));
resamp.audio_resample_ratio = audio_resample_ratio; resamp.audio_resample_ratio = audio_resample_ratio;
resamp.audio_resampler = audio_resampler; resamp.audio_resampler = audio_resampler;
@ -195,6 +196,7 @@ void DemodulatorPreThread::threadMain() {
resamp.resampler = resampler; resamp.resampler = resampler;
postInputQueue->push(resamp); postInputQueue->push(resamp);
inp.cleanup();
} }
if (!workerResults->empty()) { if (!workerResults->empty()) {

View File

@ -39,9 +39,14 @@ void DemodulatorThread::threadMain() {
DemodulatorThreadPostIQData inp; DemodulatorThreadPostIQData inp;
postInputQueue->pop(inp); postInputQueue->pop(inp);
int bufSize = inp.data.size(); if (!inp.data) {
continue;
}
int bufSize = inp.data->size();
if (!bufSize) { if (!bufSize) {
delete inp.data;
continue; continue;
} }
@ -60,7 +65,9 @@ void DemodulatorThread::threadMain() {
liquid_float_complex agc_data[out_size]; liquid_float_complex agc_data[out_size];
unsigned int num_written; unsigned int num_written;
msresamp_crcf_execute(resampler, &inp.data[0], bufSize, resampled_data, &num_written); msresamp_crcf_execute(resampler, &((*inp.data)[0]), bufSize, resampled_data, &num_written);
delete inp.data;
agc_crcf_execute_block(agc, resampled_data, num_written, agc_data); agc_crcf_execute_block(agc, resampled_data, num_written, agc_data);
@ -77,7 +84,8 @@ void DemodulatorThread::threadMain() {
AudioThreadInput ati; AudioThreadInput ati;
ati.channels = 1; ati.channels = 1;
ati.data.assign(resampled_audio_output,resampled_audio_output+num_audio_written); ati.data = new std::vector<float>;
ati.data->assign(resampled_audio_output,resampled_audio_output+num_audio_written);
if (audioInputQueue != NULL) { if (audioInputQueue != NULL) {
if (!squelch_enabled || ((agc_crcf_get_signal_level(agc)) >= 0.1)) { if (!squelch_enabled || ((agc_crcf_get_signal_level(agc)) >= 0.1)) {
@ -94,12 +102,14 @@ void DemodulatorThread::threadMain() {
if (num_vis > num_audio_written) { if (num_vis > num_audio_written) {
num_vis = num_audio_written; num_vis = num_audio_written;
} }
ati_vis.data.assign(ati.data.begin(), ati.data.begin()+num_vis); ati_vis.data = new std::vector<float>;
ati_vis.data->assign(ati.data->begin(), ati.data->begin()+num_vis);
} else { } else {
if (num_vis > num_written) { if (num_vis > num_written) {
num_vis = num_written; num_vis = num_written;
} }
ati_vis.data.assign(demod_output, demod_output + num_vis); ati_vis.data = new std::vector<float>;
ati_vis.data->assign(demod_output, demod_output + num_vis);
} }
visOutQueue->push(ati_vis); visOutQueue->push(ati_vis);

View File

@ -60,33 +60,39 @@ void SDRPostThread::threadMain() {
iqDataInQueue.load()->pop(data_in); iqDataInQueue.load()->pop(data_in);
if (data_in.data.size()) { if (data_in.data && data_in.data->size()) {
SDRThreadIQData dataOut; SDRThreadIQData dataOut;
dataOut.frequency = data_in.frequency; dataOut.frequency = data_in.frequency;
dataOut.bandwidth = data_in.bandwidth; dataOut.bandwidth = data_in.bandwidth;
dataOut.data = data_in.data; dataOut.data = data_in.data;
for (int i = 0, iMax = dataOut.data.size() / 2; i < iMax; i++) { for (int i = 0, iMax = dataOut.data->size() / 2; i < iMax; i++) {
x.real = (float) dataOut.data[i * 2] / 127.0; x.real = (float) (*dataOut.data)[i * 2] / 127.0;
x.imag = (float) dataOut.data[i * 2 + 1] / 127.0; x.imag = (float) (*dataOut.data)[i * 2 + 1] / 127.0;
iirfilt_crcf_execute(dcFilter, x, &y); iirfilt_crcf_execute(dcFilter, x, &y);
dataOut.data[i * 2] = (signed char) floor(y.real * 127.0); (*dataOut.data)[i * 2] = (signed char) floor(y.real * 127.0);
dataOut.data[i * 2 + 1] = (signed char) floor(y.imag * 127.0); (*dataOut.data)[i * 2 + 1] = (signed char) floor(y.imag * 127.0);
} }
if (iqDataOutQueue != NULL) { if (iqDataOutQueue != NULL) {
iqDataOutQueue.load()->push(dataOut); iqDataOutQueue.load()->push(dataOut);
} }
if (iqVisualQueue != NULL) { if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) {
if (iqVisualQueue.load()->empty()) { SDRThreadIQData visualDataOut;
iqVisualQueue.load()->push(dataOut); visualDataOut.data = new std::vector<signed char>;
} visualDataOut.data->assign(dataOut.data->begin(), dataOut.data->begin() + (FFT_SIZE * 2));
iqVisualQueue.load()->push(visualDataOut);
} }
std::atomic<int> *c = new std::atomic<int>;
c->store(demodulators.size());
bool demodActive = false;
if (demodulators.size()) { if (demodulators.size()) {
DemodulatorThreadIQData dummyDataOut; DemodulatorThreadIQData dummyDataOut;
dummyDataOut.frequency = data_in.frequency; dummyDataOut.frequency = data_in.frequency;
@ -94,6 +100,7 @@ void SDRPostThread::threadMain() {
DemodulatorThreadIQData demodDataOut; DemodulatorThreadIQData demodDataOut;
demodDataOut.frequency = data_in.frequency; demodDataOut.frequency = data_in.frequency;
demodDataOut.bandwidth = data_in.bandwidth; demodDataOut.bandwidth = data_in.bandwidth;
demodDataOut.setRefCount(c);
demodDataOut.data = data_in.data; demodDataOut.data = data_in.data;
std::vector<DemodulatorInstance *>::iterator i; std::vector<DemodulatorInstance *>::iterator i;
@ -106,6 +113,7 @@ void SDRPostThread::threadMain() {
if (demod->isActive()) { if (demod->isActive()) {
demod->setActive(false); demod->setActive(false);
demodQueue->push(dummyDataOut); demodQueue->push(dummyDataOut);
c->store(c->load() - 1);
continue; continue;
} }
} else if (!demod->isActive()) { } else if (!demod->isActive()) {
@ -113,8 +121,14 @@ void SDRPostThread::threadMain() {
} }
demodQueue->push(demodDataOut); demodQueue->push(demodDataOut);
demodActive = true;
} }
} }
if (!demodActive) {
delete dataOut.data;
delete c;
}
} }
} }
std::cout << "SDR post-processing thread done." << std::endl; std::cout << "SDR post-processing thread done." << std::endl;

View File

@ -156,10 +156,10 @@ void SDRThread::threadMain() {
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read);
std::vector<signed char> new_buffer; std::vector<signed char> *new_buffer = new std::vector<signed char>;
for (int i = 0; i < n_read; i++) { for (int i = 0; i < n_read; i++) {
new_buffer.push_back(buf[i] - 127); new_buffer->push_back(buf[i] - 127);
} }
double time_slice = (double) n_read / (double) sample_rate; double time_slice = (double) n_read / (double) sample_rate;

View File

@ -38,14 +38,14 @@ class SDRThreadIQData {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int bandwidth; unsigned int bandwidth;
std::vector<signed char> data; std::vector<signed char> *data;
SDRThreadIQData() : SDRThreadIQData() :
frequency(0), bandwidth(0) { frequency(0), bandwidth(0), data(NULL) {
} }
SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector<signed char> data) : SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector<signed char> *data) :
data(data), frequency(frequency), bandwidth(bandwidth) { data(data), frequency(frequency), bandwidth(bandwidth) {
} }

View File

@ -29,7 +29,7 @@ SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) :
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0) { wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0) {
int in_block_size = BUF_SIZE / 2; int in_block_size = FFT_SIZE;
int out_block_size = FFT_SIZE; int out_block_size = FFT_SIZE;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size); in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size);
@ -80,7 +80,7 @@ void SpectrumCanvas::setData(std::vector<signed char> *data) {
spectrum_points.resize(FFT_SIZE * 2); spectrum_points.resize(FFT_SIZE * 2);
} }
for (int i = 0; i < BUF_SIZE / 2; i++) { for (int i = 0; i < FFT_SIZE; i++) {
in[i][0] = (float) (*data)[i * 2] / 127.0f; in[i][0] = (float) (*data)[i * 2] / 127.0f;
in[i][1] = (float) (*data)[i * 2 + 1] / 127.0f; in[i][1] = (float) (*data)[i * 2 + 1] / 127.0f;
} }

View File

@ -33,7 +33,7 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown( wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(
false), altDown(false), ctrlDown(false), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0) { false), altDown(false), ctrlDown(false), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0) {
int in_block_size = BUF_SIZE / 2; int in_block_size = FFT_SIZE;
int out_block_size = FFT_SIZE; int out_block_size = FFT_SIZE;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size); in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size);
@ -204,7 +204,7 @@ void WaterfallCanvas::setData(std::vector<signed char> *data) {
spectrum_points.resize(FFT_SIZE * 2); spectrum_points.resize(FFT_SIZE * 2);
} }
for (int i = 0; i < BUF_SIZE / 2; i++) { for (int i = 0; i < FFT_SIZE; i++) {
in[i][0] = (float) (*data)[i * 2] / 127.0f; in[i][0] = (float) (*data)[i * 2] / 127.0f;
in[i][1] = (float) (*data)[i * 2 + 1] / 127.0f; in[i][1] = (float) (*data)[i * 2 + 1] / 127.0f;
} }