From 312b25f55a2f3845047d9e5e8cc89a6cc9150bd9 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 22 Dec 2014 19:43:56 -0500 Subject: [PATCH] Changed data transaction objects to use pointers --- src/AppFrame.cpp | 19 +++++++----- src/audio/AudioThread.cpp | 24 ++++++++++---- src/audio/AudioThread.h | 4 +-- src/demod/DemodDefs.h | 50 +++++++++++++++++++++++------- src/demod/DemodulatorPreThread.cpp | 10 +++--- src/demod/DemodulatorThread.cpp | 20 +++++++++--- src/sdr/SDRPostThread.cpp | 36 ++++++++++++++------- src/sdr/SDRThread.cpp | 4 +-- src/sdr/SDRThread.h | 6 ++-- src/visual/SpectrumCanvas.cpp | 4 +-- src/visual/WaterfallCanvas.cpp | 4 +-- 11 files changed, 125 insertions(+), 56 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 2c80502..f71556a 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -99,9 +99,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) { SDRThreadIQData iqData; wxGetApp().getIQVisualQueue()->pop(iqData); - if (iqData.data.size()) { - spectrumCanvas->setData(&iqData.data); - waterfallCanvas->setData(&iqData.data); + if (iqData.data && iqData.data->size()) { + spectrumCanvas->setData(iqData.data); + waterfallCanvas->setData(iqData.data); + + delete iqData.data; } else { std::cout << "Incoming IQ data empty?" << std::endl; } @@ -111,17 +113,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) { if (!wxGetApp().getAudioVisualQueue()->empty()) { AudioThreadInput demodAudioData; wxGetApp().getAudioVisualQueue()->pop(demodAudioData); - if (demodAudioData.data.size()) { + if (demodAudioData.data && demodAudioData.data->size()) { - if (scopeCanvas->waveform_points.size() != demodAudioData.data.size()*2) { - scopeCanvas->waveform_points.resize(demodAudioData.data.size()*2); + if (scopeCanvas->waveform_points.size() != demodAudioData.data->size()*2) { + scopeCanvas->waveform_points.resize(demodAudioData.data->size()*2); } - for (int i = 0, iMax = demodAudioData.data.size(); i < iMax; i++) { - scopeCanvas->waveform_points[i * 2 + 1] = demodAudioData.data[i] * 0.5f; + 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] = ((double) i / (double) iMax); } + delete demodAudioData.data; } else { std::cout << "Incoming Demodulator data empty?" << std::endl; } diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index b429ec3..d613cb5 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -65,7 +65,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu continue; } - if (srcmix->currentInput.channels == 0) { + if (srcmix->currentInput.channels == 0 || !srcmix->currentInput.data) { if (!srcmix->inputQueue->empty()) { 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; } - if (src->currentInput.channels == 0) { + if (src->currentInput.channels == 0 || !src->currentInput.data) { if (!src->inputQueue->empty()) { + if (src->currentInput.data) { + delete src->currentInput.data; + } src->inputQueue->pop(src->currentInput); } return 0; @@ -119,26 +122,29 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu if (src->currentInput.channels == 1) { 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) { break; } src->inputQueue->pop(src->currentInput); 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++; } } else { 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) { break; } src->inputQueue->pop(src->currentInput); 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++; } } @@ -302,11 +308,17 @@ void AudioThread::setActive(bool state) { deviceController[parameters.deviceId]->bindThread(this); while (!inputQueue->empty()) { // flush queue inputQueue->pop(dummy); + if (dummy.data) { + delete dummy.data; + } } } else if (!state && active) { deviceController[parameters.deviceId]->removeThread(this); while (!inputQueue->empty()) { // flush queue inputQueue->pop(dummy); + if (dummy.data) { + delete dummy.data; + } } } #endif diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 9ea135a..f2446e4 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -24,7 +24,7 @@ public: int sampleRate; 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 data; + std::vector *data; }; class AudioThreadCommand { diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index e5822c1..22df172 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -4,6 +4,8 @@ #include "CubicSDRDefs.h" #include "liquid/liquid.h" +#include + enum DemodulatorType { DEMOD_TYPE_NULL, DEMOD_TYPE_AM, @@ -57,19 +59,37 @@ class DemodulatorThreadIQData { public: unsigned int frequency; unsigned int bandwidth; - std::vector data; + std::vector *data; + std::atomic *refCount; DemodulatorThreadIQData() : - frequency(0), bandwidth(0) { + frequency(0), bandwidth(0), data(NULL), refCount(0) { } - DemodulatorThreadIQData(unsigned int bandwidth, unsigned int frequency, - std::vector data) : - data(data), frequency(frequency), bandwidth(bandwidth) { - + DemodulatorThreadIQData(const DemodulatorThreadIQData& o) { + frequency = o.frequency; + bandwidth = o.bandwidth; + data = o.data; + refCount = o.refCount; } + void setRefCount(std::atomic *rc) { + refCount = rc; + } + + void cleanup() { + if (refCount) { + (*refCount)--; + if ((*refCount) <= 0) { + delete data; + data = NULL; + delete refCount; + refCount = NULL; + } + } + } + ~DemodulatorThreadIQData() { } @@ -77,16 +97,24 @@ public: class DemodulatorThreadPostIQData { public: - std::vector data; + std::vector *data; float audio_resample_ratio; msresamp_rrrf audio_resampler; float resample_ratio; 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() { } @@ -99,15 +127,15 @@ public: unsigned int sampleRate; unsigned char channels; - std::vector data; + std::vector *data; DemodulatorThreadAudioData() : - sampleRate(0), frequency(0), channels(0) { + sampleRate(0), frequency(0), channels(0), data(NULL) { } DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, - std::vector data) : + std::vector *data) : data(data), sampleRate(sampleRate), frequency(frequency), channels( 1) { diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 19775ec..9e2c117 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -157,8 +157,8 @@ void DemodulatorPreThread::threadMain() { continue; } - std::vector *data = &inp.data; - if (data->size()) { + std::vector *data = inp.data; + if (data && data->size()) { int bufSize = data->size() / 2; liquid_float_complex in_buf_data[bufSize]; @@ -185,9 +185,10 @@ void DemodulatorPreThread::threadMain() { } DemodulatorThreadPostIQData resamp; - resamp.data.resize(bufSize); + resamp.data = new std::vector; + 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_resampler = audio_resampler; @@ -195,6 +196,7 @@ void DemodulatorPreThread::threadMain() { resamp.resampler = resampler; postInputQueue->push(resamp); + inp.cleanup(); } if (!workerResults->empty()) { diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index f9befc5..8748a78 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -39,9 +39,14 @@ void DemodulatorThread::threadMain() { DemodulatorThreadPostIQData inp; postInputQueue->pop(inp); - int bufSize = inp.data.size(); + if (!inp.data) { + continue; + } + + int bufSize = inp.data->size(); if (!bufSize) { + delete inp.data; continue; } @@ -60,7 +65,9 @@ void DemodulatorThread::threadMain() { liquid_float_complex agc_data[out_size]; 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); @@ -77,7 +84,8 @@ void DemodulatorThread::threadMain() { AudioThreadInput ati; ati.channels = 1; - ati.data.assign(resampled_audio_output,resampled_audio_output+num_audio_written); + ati.data = new std::vector; + ati.data->assign(resampled_audio_output,resampled_audio_output+num_audio_written); if (audioInputQueue != NULL) { if (!squelch_enabled || ((agc_crcf_get_signal_level(agc)) >= 0.1)) { @@ -94,12 +102,14 @@ void DemodulatorThread::threadMain() { if (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; + ati_vis.data->assign(ati.data->begin(), ati.data->begin()+num_vis); } else { if (num_vis > num_written) { num_vis = num_written; } - ati_vis.data.assign(demod_output, demod_output + num_vis); + ati_vis.data = new std::vector; + ati_vis.data->assign(demod_output, demod_output + num_vis); } visOutQueue->push(ati_vis); diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 5487c68..9b465ae 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -45,7 +45,7 @@ void SDRPostThread::threadMain() { #ifdef __APPLE__ pthread_t tID = pthread_self(); // ID of this thread int priority = sched_get_priority_max( SCHED_FIFO) - 1; - sched_param prio = { priority }; // scheduling priority of thread + sched_param prio = {priority}; // scheduling priority of thread pthread_setschedparam(tID, SCHED_FIFO, &prio); #endif @@ -60,33 +60,39 @@ void SDRPostThread::threadMain() { iqDataInQueue.load()->pop(data_in); - if (data_in.data.size()) { + if (data_in.data && data_in.data->size()) { SDRThreadIQData dataOut; dataOut.frequency = data_in.frequency; dataOut.bandwidth = data_in.bandwidth; dataOut.data = data_in.data; - for (int i = 0, iMax = dataOut.data.size() / 2; i < iMax; i++) { - x.real = (float) dataOut.data[i * 2] / 127.0; - x.imag = (float) dataOut.data[i * 2 + 1] / 127.0; + for (int i = 0, iMax = dataOut.data->size() / 2; i < iMax; i++) { + x.real = (float) (*dataOut.data)[i * 2] / 127.0; + x.imag = (float) (*dataOut.data)[i * 2 + 1] / 127.0; iirfilt_crcf_execute(dcFilter, x, &y); - 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] = (signed char) floor(y.real * 127.0); + (*dataOut.data)[i * 2 + 1] = (signed char) floor(y.imag * 127.0); } if (iqDataOutQueue != NULL) { iqDataOutQueue.load()->push(dataOut); } - if (iqVisualQueue != NULL) { - if (iqVisualQueue.load()->empty()) { - iqVisualQueue.load()->push(dataOut); - } + if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) { + SDRThreadIQData visualDataOut; + visualDataOut.data = new std::vector; + visualDataOut.data->assign(dataOut.data->begin(), dataOut.data->begin() + (FFT_SIZE * 2)); + iqVisualQueue.load()->push(visualDataOut); } + std::atomic *c = new std::atomic; + c->store(demodulators.size()); + + bool demodActive = false; + if (demodulators.size()) { DemodulatorThreadIQData dummyDataOut; dummyDataOut.frequency = data_in.frequency; @@ -94,6 +100,7 @@ void SDRPostThread::threadMain() { DemodulatorThreadIQData demodDataOut; demodDataOut.frequency = data_in.frequency; demodDataOut.bandwidth = data_in.bandwidth; + demodDataOut.setRefCount(c); demodDataOut.data = data_in.data; std::vector::iterator i; @@ -106,6 +113,7 @@ void SDRPostThread::threadMain() { if (demod->isActive()) { demod->setActive(false); demodQueue->push(dummyDataOut); + c->store(c->load() - 1); continue; } } else if (!demod->isActive()) { @@ -113,8 +121,14 @@ void SDRPostThread::threadMain() { } demodQueue->push(demodDataOut); + demodActive = true; } } + + if (!demodActive) { + delete dataOut.data; + delete c; + } } } std::cout << "SDR post-processing thread done." << std::endl; diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index adfffb0..30f34a6 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -156,10 +156,10 @@ void SDRThread::threadMain() { rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); - std::vector new_buffer; + std::vector *new_buffer = new std::vector; 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; diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index ab76759..72b45b5 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -38,14 +38,14 @@ class SDRThreadIQData { public: unsigned int frequency; unsigned int bandwidth; - std::vector data; + std::vector *data; SDRThreadIQData() : - frequency(0), bandwidth(0) { + frequency(0), bandwidth(0), data(NULL) { } - SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector data) : + SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector *data) : data(data), frequency(frequency), bandwidth(bandwidth) { } diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 0974d3b..1ac98ef 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -29,7 +29,7 @@ SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, 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; in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size); @@ -80,7 +80,7 @@ void SpectrumCanvas::setData(std::vector *data) { 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][1] = (float) (*data)[i * 2 + 1] / 127.0f; } diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 6318996..d9426b5 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -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( 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; in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * in_block_size); @@ -204,7 +204,7 @@ void WaterfallCanvas::setData(std::vector *data) { 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][1] = (float) (*data)[i * 2 + 1] / 127.0f; }