From 312b25f55a2f3845047d9e5e8cc89a6cc9150bd9 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 22 Dec 2014 19:43:56 -0500 Subject: [PATCH 01/13] 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; } From 24d06e13d7a2651a743009958fc9361c507740d8 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 22 Dec 2014 21:12:13 -0500 Subject: [PATCH 02/13] Fix for various threading crashes during stress test --- src/audio/AudioThread.cpp | 37 ++++++++++--- src/demod/DemodDefs.h | 6 +- src/demod/DemodulatorThread.cpp | 3 +- src/sdr/SDRPostThread.cpp | 98 ++++++++++++++++++++++----------- src/sdr/SDRPostThread.h | 2 + 5 files changed, 101 insertions(+), 45 deletions(-) diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index d613cb5..1e95c63 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -67,29 +67,43 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu if (srcmix->currentInput.channels == 0 || !srcmix->currentInput.data) { if (!srcmix->inputQueue->empty()) { + if (srcmix->currentInput.data) { + delete srcmix->currentInput.data; + } srcmix->inputQueue->pop(srcmix->currentInput); + srcmix->audio_queue_ptr = 0; } - continue; + return 0; } if (srcmix->currentInput.channels == 1) { for (int i = 0; i < nBufferFrames; i++) { - if (srcmix->audio_queue_ptr >= srcmix->currentInput.data.size()) { + if (srcmix->audio_queue_ptr >= srcmix->currentInput.data->size()) { + if (srcmix->currentInput.data) { + delete srcmix->currentInput.data; + } srcmix->inputQueue->pop(srcmix->currentInput); srcmix->audio_queue_ptr = 0; } - float v = srcmix->currentInput.data[srcmix->audio_queue_ptr] * src->gain; - out[i * 2] += v; - out[i * 2 + 1] += v; + if (srcmix->currentInput.data && srcmix->currentInput.data->size()) { + float v = (*srcmix->currentInput.data)[srcmix->audio_queue_ptr] * src->gain; + out[i * 2] += v; + out[i * 2 + 1] += v; + } srcmix->audio_queue_ptr++; } } else { for (int i = 0, iMax = src->currentInput.channels * nBufferFrames; i < iMax; i++) { if (srcmix->audio_queue_ptr >= srcmix->currentInput.data.size()) { + if (srcmix->currentInput.data) { + delete srcmix->currentInput.data; + } srcmix->inputQueue->pop(srcmix->currentInput); srcmix->audio_queue_ptr = 0; } - out[i] = out[i] + srcmix->currentInput.data[srcmix->audio_queue_ptr] * src->gain; + if (srcmix->currentInput.data && srcmix->currentInput.data->size()) { + out[i] = out[i] + (*srcmix->currentInput.data)[srcmix->audio_queue_ptr] * src->gain; + } srcmix->audio_queue_ptr++; } } @@ -116,6 +130,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu delete src->currentInput.data; } src->inputQueue->pop(src->currentInput); + src->audio_queue_ptr = 0; } return 0; } @@ -132,7 +147,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu 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; + if (src->currentInput.data && src->currentInput.data->size()) { + out[i * 2] = out[i * 2 + 1] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain; + } src->audio_queue_ptr++; } } else { @@ -144,7 +161,9 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu src->inputQueue->pop(src->currentInput); src->audio_queue_ptr = 0; } - out[i] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain; + if (src->currentInput.data && src->currentInput.data->size()) { + out[i] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain; + } src->audio_queue_ptr++; } } @@ -305,13 +324,13 @@ void AudioThread::setActive(bool state) { #ifdef __APPLE__ AudioThreadInput dummy; if (state && !active) { - deviceController[parameters.deviceId]->bindThread(this); while (!inputQueue->empty()) { // flush queue inputQueue->pop(dummy); if (dummy.data) { delete dummy.data; } } + deviceController[parameters.deviceId]->bindThread(this); } else if (!state && active) { deviceController[parameters.deviceId]->removeThread(this); while (!inputQueue->empty()) { // flush queue diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 22df172..a9129d2 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -63,7 +63,7 @@ public: std::atomic *refCount; DemodulatorThreadIQData() : - frequency(0), bandwidth(0), data(NULL), refCount(0) { + frequency(0), bandwidth(0), data(NULL), refCount(NULL) { } @@ -80,8 +80,8 @@ public: void cleanup() { if (refCount) { - (*refCount)--; - if ((*refCount) <= 0) { + refCount->store(refCount->load()-1); + if (refCount->load() == 0) { delete data; data = NULL; delete refCount; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 8748a78..b0f059d 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -67,8 +67,6 @@ void DemodulatorThread::threadMain() { unsigned int 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); float audio_resample_ratio = inp.audio_resample_ratio; @@ -138,6 +136,7 @@ void DemodulatorThread::threadMain() { } } + delete inp.data; } if (resampler != NULL) { diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 9b465ae..3b74ae3 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -11,7 +11,7 @@ SDRPostThread::~SDRPostThread() { } void SDRPostThread::bindDemodulator(DemodulatorInstance *demod) { - demodulators.push_back(demod); + demodulators_add.push_back(demod); } void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) { @@ -19,13 +19,7 @@ void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) { return; } - std::vector::iterator i; - - i = std::find(demodulators.begin(), demodulators.end(), demod); - - if (i != demodulators.end()) { - demodulators.erase(i); - } + demodulators_remove.push_back(demod); } void SDRPostThread::setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) { @@ -88,48 +82,90 @@ void SDRPostThread::threadMain() { iqVisualQueue.load()->push(visualDataOut); } - std::atomic *c = new std::atomic; - c->store(demodulators.size()); - bool demodActive = false; + if (demodulators_add.size()) { + while (!demodulators_add.empty()) { + demodulators.push_back(demodulators_add.back()); + demodulators_add.pop_back(); + } + } + if (demodulators_remove.size()) { + while (!demodulators_remove.empty()) { + DemodulatorInstance *demod = demodulators_remove.back(); + demodulators_remove.pop_back(); + + std::vector::iterator i = std::find(demodulators.begin(), demodulators.end(), demod); + + if (i != demodulators.end()) { + demodulators.erase(i); + } + } + } + + int activeDemods = 0; + bool pushedData = false; + std::atomic *c = new std::atomic; if (demodulators.size()) { - DemodulatorThreadIQData dummyDataOut; - dummyDataOut.frequency = data_in.frequency; - dummyDataOut.bandwidth = data_in.bandwidth; - DemodulatorThreadIQData demodDataOut; - demodDataOut.frequency = data_in.frequency; - demodDataOut.bandwidth = data_in.bandwidth; - demodDataOut.setRefCount(c); - demodDataOut.data = data_in.data; std::vector::iterator i; for (i = demodulators.begin(); i != demodulators.end(); i++) { DemodulatorInstance *demod = *i; - DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod; if (demod->getParams().frequency != data_in.frequency - && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0) * 1.15)) { - if (demod->isActive()) { - demod->setActive(false); - demodQueue->push(dummyDataOut); - c->store(c->load() - 1); + && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { + continue; + } + activeDemods++; + } + + c->store(activeDemods); + + bool demodActive = false; + + if (demodulators.size()) { + DemodulatorThreadIQData dummyDataOut; + dummyDataOut.frequency = data_in.frequency; + dummyDataOut.bandwidth = data_in.bandwidth; + dummyDataOut.data = NULL; + DemodulatorThreadIQData demodDataOut; + demodDataOut.frequency = data_in.frequency; + demodDataOut.bandwidth = data_in.bandwidth; + demodDataOut.setRefCount(c); + demodDataOut.data = data_in.data; + + std::vector::iterator i; + for (i = demodulators.begin(); i != demodulators.end(); i++) { + DemodulatorInstance *demod = *i; + DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod; + + if (demod->getParams().frequency != data_in.frequency + && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { + if (demod->isActive()) { + demod->setActive(false); + demodQueue->push(dummyDataOut); + } + } else if (!demod->isActive()) { + demod->setActive(true); + } + + if (!demod->isActive()) { continue; } - } else if (!demod->isActive()) { - demod->setActive(true); - } - demodQueue->push(demodDataOut); - demodActive = true; + demodQueue->push(demodDataOut); + pushedData = true; + } } } - if (!demodActive) { + if (!pushedData) { delete dataOut.data; delete c; } } + + } std::cout << "SDR post-processing thread done." << std::endl; } diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index bd71b76..928cf07 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -26,6 +26,8 @@ protected: std::atomic iqVisualQueue; std::vector demodulators; + std::vector demodulators_add; + std::vector demodulators_remove; std::atomic terminated; iirfilt_crcf dcFilter; }; From 1dc218d346e307060a8d4afbdb2af2a1f77cc73c Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 22 Dec 2014 21:31:53 -0500 Subject: [PATCH 03/13] Disable FIR filter -- decimation is enough? --- src/demod/DemodulatorPreThread.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 9e2c117..eb71a6b 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -186,9 +186,10 @@ void DemodulatorPreThread::threadMain() { DemodulatorThreadPostIQData resamp; resamp.data = new std::vector; - resamp.data->resize(bufSize); +// resamp.data->resize(bufSize); + resamp.data->assign(in_buf,in_buf+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; From 703501f32d8238f28c28e102c4bb7073f5bb1673 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 22 Dec 2014 23:27:52 -0500 Subject: [PATCH 04/13] OSX fixes --- src/audio/AudioThread.cpp | 2 +- src/demod/DemodDefs.h | 32 +++++++++++++-------------- src/demod/DemodulatorPreThread.cpp | 19 +++++++++------- src/sdr/SDRPostThread.cpp | 35 ++++++++++++------------------ 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 1e95c63..9095186 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -94,7 +94,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu } } else { for (int i = 0, iMax = src->currentInput.channels * nBufferFrames; i < iMax; i++) { - if (srcmix->audio_queue_ptr >= srcmix->currentInput.data.size()) { + if (srcmix->audio_queue_ptr >= srcmix->currentInput.data->size()) { if (srcmix->currentInput.data) { delete srcmix->currentInput.data; } diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index a9129d2..88a7d25 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -59,11 +59,10 @@ class DemodulatorThreadIQData { public: unsigned int frequency; unsigned int bandwidth; - std::vector *data; - std::atomic *refCount; + std::vector data; DemodulatorThreadIQData() : - frequency(0), bandwidth(0), data(NULL), refCount(NULL) { + frequency(0), bandwidth(0), refCount(0) { } @@ -71,28 +70,27 @@ public: frequency = o.frequency; bandwidth = o.bandwidth; data = o.data; - refCount = o.refCount; + refCount.store(o.refCount.load()); } - void setRefCount(std::atomic *rc) { - refCount = rc; + void setRefCount(int rc) { + refCount.store(rc); } - void cleanup() { - if (refCount) { - refCount->store(refCount->load()-1); - if (refCount->load() == 0) { - delete data; - data = NULL; - delete refCount; - refCount = NULL; - } - } + void decRefCount() { + refCount.store(refCount.load()-1); + } + + int getRefCount() { + return refCount.load(); } ~DemodulatorThreadIQData() { } +private: + std::atomic refCount; + }; class DemodulatorThreadPostIQData { @@ -146,7 +144,7 @@ public: } }; -typedef ThreadQueue DemodulatorThreadInputQueue; +typedef ThreadQueue DemodulatorThreadInputQueue; typedef ThreadQueue DemodulatorThreadPostInputQueue; typedef ThreadQueue DemodulatorThreadCommandQueue; typedef ThreadQueue DemodulatorThreadControlCommandQueue; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index eb71a6b..e0635e8 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -100,7 +100,7 @@ void DemodulatorPreThread::threadMain() { std::cout << "Demodulator preprocessor thread started.." << std::endl; while (!terminated) { - DemodulatorThreadIQData inp; + DemodulatorThreadIQData *inp; inputQueue->pop(inp); bool bandwidthChanged = false; @@ -144,9 +144,9 @@ void DemodulatorPreThread::threadMain() { } // Requested frequency is not center, shift it into the center! - if (inp.frequency != params.frequency) { - if ((params.frequency - inp.frequency) != shift_freq) { - shift_freq = params.frequency - inp.frequency; + if (inp->frequency != params.frequency) { + if ((params.frequency - inp->frequency) != shift_freq) { + shift_freq = params.frequency - inp->frequency; if (abs(shift_freq) <= (int) ((float) (SRATE / 2) * 1.5)) { nco_crcf_set_frequency(nco_shift, (2.0 * M_PI) * (((float) abs(shift_freq)) / ((float) SRATE))); } @@ -157,8 +157,8 @@ void DemodulatorPreThread::threadMain() { continue; } - std::vector *data = inp.data; - if (data && data->size()) { + std::vector *data = &inp->data; + if (data->size()) { int bufSize = data->size() / 2; liquid_float_complex in_buf_data[bufSize]; @@ -197,7 +197,10 @@ void DemodulatorPreThread::threadMain() { resamp.resampler = resampler; postInputQueue->push(resamp); - inp.cleanup(); + inp->decRefCount(); + if (inp->getRefCount()<=0) { + delete inp; + } } if (!workerResults->empty()) { @@ -236,7 +239,7 @@ void DemodulatorPreThread::threadMain() { void DemodulatorPreThread::terminate() { terminated = true; - DemodulatorThreadIQData inp; // push dummy to nudge queue + DemodulatorThreadIQData *inp = new DemodulatorThreadIQData; // push dummy to nudge queue inputQueue->push(inp); workerThread->terminate(); } diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 3b74ae3..bee87f9 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -39,7 +39,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 @@ -82,7 +82,6 @@ void SDRPostThread::threadMain() { iqVisualQueue.load()->push(visualDataOut); } - if (demodulators_add.size()) { while (!demodulators_add.empty()) { demodulators.push_back(demodulators_add.back()); @@ -104,7 +103,6 @@ void SDRPostThread::threadMain() { int activeDemods = 0; bool pushedData = false; - std::atomic *c = new std::atomic; if (demodulators.size()) { @@ -119,20 +117,14 @@ void SDRPostThread::threadMain() { activeDemods++; } - c->store(activeDemods); - bool demodActive = false; if (demodulators.size()) { - DemodulatorThreadIQData dummyDataOut; - dummyDataOut.frequency = data_in.frequency; - dummyDataOut.bandwidth = data_in.bandwidth; - dummyDataOut.data = NULL; - DemodulatorThreadIQData demodDataOut; - demodDataOut.frequency = data_in.frequency; - demodDataOut.bandwidth = data_in.bandwidth; - demodDataOut.setRefCount(c); - demodDataOut.data = data_in.data; + DemodulatorThreadIQData *demodDataOut = new DemodulatorThreadIQData; + demodDataOut->frequency = data_in.frequency; + demodDataOut->bandwidth = data_in.bandwidth; + demodDataOut->setRefCount(activeDemods); + demodDataOut->data.assign(dataOut.data->begin(), dataOut.data->begin() + dataOut.data->size()); std::vector::iterator i; for (i = demodulators.begin(); i != demodulators.end(); i++) { @@ -143,6 +135,9 @@ void SDRPostThread::threadMain() { && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { if (demod->isActive()) { demod->setActive(false); + DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData; + dummyDataOut->frequency = data_in.frequency; + dummyDataOut->bandwidth = data_in.bandwidth; demodQueue->push(dummyDataOut); } } else if (!demod->isActive()) { @@ -156,16 +151,14 @@ void SDRPostThread::threadMain() { demodQueue->push(demodDataOut); pushedData = true; } + + if (!pushedData) { + delete demodDataOut; + } } } - - if (!pushedData) { - delete dataOut.data; - delete c; - } + delete dataOut.data; } - - } std::cout << "SDR post-processing thread done." << std::endl; } From 8ce3065bce68671b77daa2c27ebd02394fe5e45b Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 23 Dec 2014 01:12:14 -0500 Subject: [PATCH 05/13] cleanup / refactor / profiled --- src/CubicSDR.h | 3 +-- src/audio/AudioThread.cpp | 3 +-- src/demod/DemodDefs.h | 30 +++++++-------------------- src/demod/DemodulatorPreThread.cpp | 14 ++++++------- src/demod/DemodulatorThread.cpp | 32 +++++++++++++---------------- src/demod/DemodulatorWorkerThread.h | 15 +++++++------- src/sdr/SDRPostThread.cpp | 2 +- src/sdr/SDRThread.cpp | 2 ++ src/sdr/SDRThread.h | 2 +- src/util/GLFont.cpp | 6 +++--- src/util/MouseTracker.h | 10 ++++----- src/util/Timer.cpp | 2 +- src/visual/WaterfallCanvas.cpp | 3 +-- 13 files changed, 50 insertions(+), 74 deletions(-) diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 5128368..4790aef 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -20,8 +20,7 @@ class CubicSDR: public wxApp { public: CubicSDR() : - m_glContext(NULL), t_PostSDR(NULL), t_SDR(NULL), audioVisualQueue(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), frequency( - DEFAULT_FREQ), sdrPostThread(NULL), iqPostDataQueue(NULL), sdrThread(NULL) { + m_glContext(NULL), frequency(DEFAULT_FREQ), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL) { } diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 9095186..706ce1c 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -10,8 +10,7 @@ std::map AudioThread::deviceThread; #endif AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) : - inputQueue(inputQueue), terminated(false), audio_queue_ptr(0), underflow_count(0), threadQueueNotify(threadQueueNotify), gain(1.0), active( - false) { +inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify(threadQueueNotify) { #ifdef __APPLE__ boundThreads = new std::vector; #endif diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 88a7d25..e6cf822 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -26,12 +26,12 @@ public: }; DemodulatorThreadCommand() : - cmd(DEMOD_THREAD_CMD_NULL), int_value(0), context(NULL) { + cmd(DEMOD_THREAD_CMD_NULL), context(NULL), int_value(0) { } DemodulatorThreadCommand(DemodulatorThreadCommandEnum cmd) : - cmd(cmd), int_value(0), context(NULL) { + cmd(cmd), context(NULL), int_value(0) { } @@ -66,13 +66,6 @@ public: } - DemodulatorThreadIQData(const DemodulatorThreadIQData& o) { - frequency = o.frequency; - bandwidth = o.bandwidth; - data = o.data; - refCount.store(o.refCount.load()); - } - void setRefCount(int rc) { refCount.store(rc); } @@ -95,24 +88,16 @@ private: 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), data(NULL) { + DemodulatorThreadPostIQData(): audio_resample_ratio(0), audio_resampler(NULL), resample_ratio(0), resampler(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() { } @@ -128,14 +113,13 @@ public: std::vector *data; DemodulatorThreadAudioData() : - sampleRate(0), frequency(0), channels(0), data(NULL) { + frequency(0), sampleRate(0), channels(0), data(NULL) { } DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, std::vector *data) : - data(data), sampleRate(sampleRate), frequency(frequency), channels( - 1) { + frequency(frequency), sampleRate(sampleRate), channels(1), data(data) { } @@ -145,7 +129,7 @@ public: }; typedef ThreadQueue DemodulatorThreadInputQueue; -typedef ThreadQueue DemodulatorThreadPostInputQueue; +typedef ThreadQueue DemodulatorThreadPostInputQueue; typedef ThreadQueue DemodulatorThreadCommandQueue; typedef ThreadQueue DemodulatorThreadControlCommandQueue; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index e0635e8..8e70537 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -184,17 +184,15 @@ void DemodulatorPreThread::threadMain() { out_buf = temp_buf; } - DemodulatorThreadPostIQData resamp; - resamp.data = new std::vector; -// resamp.data->resize(bufSize); - resamp.data->assign(in_buf,in_buf+bufSize); + DemodulatorThreadPostIQData *resamp = new DemodulatorThreadPostIQData; + resamp->data.assign(in_buf,in_buf+bufSize); // firfilt_crcf_execute_block(fir_filter, in_buf, bufSize, &((*resamp.data)[0])); - resamp.audio_resample_ratio = audio_resample_ratio; - resamp.audio_resampler = audio_resampler; - resamp.resample_ratio = resample_ratio; - resamp.resampler = resampler; + resamp->audio_resample_ratio = audio_resample_ratio; + resamp->audio_resampler = audio_resampler; + resamp->resample_ratio = resample_ratio; + resamp->resampler = resampler; postInputQueue->push(resamp); inp->decRefCount(); diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index b0f059d..e66ec78 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -7,7 +7,7 @@ #endif DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : - postInputQueue(pQueue), visOutQueue(NULL), terminated(false), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), agc(NULL), squelch_enabled(false), squelch_level(0), squelch_tolerance(0) { + postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), terminated(false), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelch_level(0), squelch_tolerance(0), squelch_enabled(false) { float kf = 0.5; // modulation factor fdem = freqdem_create(kf); @@ -36,40 +36,36 @@ void DemodulatorThread::threadMain() { std::cout << "Demodulator thread started.." << std::endl; while (!terminated) { - DemodulatorThreadPostIQData inp; + DemodulatorThreadPostIQData *inp; postInputQueue->pop(inp); - if (!inp.data) { - continue; - } - - int bufSize = inp.data->size(); + int bufSize = inp->data.size(); if (!bufSize) { - delete inp.data; + delete inp; continue; } if (resampler == NULL) { - resampler = inp.resampler; - audio_resampler = inp.audio_resampler; - } else if (resampler != inp.resampler) { + resampler = inp->resampler; + audio_resampler = inp->audio_resampler; + } else if (resampler != inp->resampler) { msresamp_crcf_destroy(resampler); msresamp_rrrf_destroy(audio_resampler); - resampler = inp.resampler; - audio_resampler = inp.audio_resampler; + resampler = inp->resampler; + audio_resampler = inp->audio_resampler; } - int out_size = ceil((float) (bufSize) * inp.resample_ratio); + int out_size = ceil((float) (bufSize) * inp->resample_ratio); liquid_float_complex resampled_data[out_size]; 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); agc_crcf_execute_block(agc, resampled_data, num_written, agc_data); - float audio_resample_ratio = inp.audio_resample_ratio; + float audio_resample_ratio = inp->audio_resample_ratio; float demod_output[num_written]; freqdem_demodulate_block(fdem, agc_data, num_written, demod_output); @@ -136,7 +132,7 @@ void DemodulatorThread::threadMain() { } } - delete inp.data; + delete inp; } if (resampler != NULL) { @@ -156,6 +152,6 @@ void DemodulatorThread::threadMain() { void DemodulatorThread::terminate() { terminated = true; - DemodulatorThreadPostIQData inp; // push dummy to nudge queue + DemodulatorThreadPostIQData *inp = new DemodulatorThreadPostIQData; // push dummy to nudge queue postInputQueue->push(inp); } diff --git a/src/demod/DemodulatorWorkerThread.h b/src/demod/DemodulatorWorkerThread.h index 950b5f1..8edcec2 100644 --- a/src/demod/DemodulatorWorkerThread.h +++ b/src/demod/DemodulatorWorkerThread.h @@ -22,17 +22,19 @@ public: }; DemodulatorWorkerThreadResult() : - cmd(DEMOD_WORKER_THREAD_RESULT_NULL), audioSampleRate(0), bandwidth(0), inputRate(0), fir_filter(NULL), resampler(NULL), resample_ratio( - 0), audio_resampler(NULL), audio_resample_ratio(0) { + cmd(DEMOD_WORKER_THREAD_RESULT_NULL), fir_filter(NULL), resampler(NULL), resample_ratio( + 0), audio_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth(0), audioSampleRate(0) { } DemodulatorWorkerThreadResult(DemodulatorThreadResultEnum cmd) : - cmd(cmd), audioSampleRate(0), bandwidth(0), inputRate(0), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio( - 0) { + cmd(cmd), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio( + 0), inputRate(0), bandwidth(0), audioSampleRate(0) { } + DemodulatorThreadResultEnum cmd; + firfilt_crcf fir_filter; msresamp_crcf resampler; float resample_ratio; @@ -43,7 +45,6 @@ public: unsigned int bandwidth; unsigned int audioSampleRate; - DemodulatorThreadResultEnum cmd; }; class DemodulatorWorkerThreadCommand { @@ -62,12 +63,12 @@ public: } + DemodulatorThreadCommandEnum cmd; + unsigned int frequency; unsigned int inputRate; unsigned int bandwidth; unsigned int audioSampleRate; - - DemodulatorThreadCommandEnum cmd; }; typedef ThreadQueue DemodulatorThreadWorkerCommandQueue; diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index bee87f9..6f2b84c 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -4,7 +4,7 @@ #include "CubicSDR.h" SDRPostThread::SDRPostThread() : - iqDataInQueue(NULL), iqDataOutQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL), sample_rate(SRATE) { + sample_rate(SRATE), iqDataOutQueue(NULL), iqDataInQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL) { } SDRPostThread::~SDRPostThread() { diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index 30f34a6..adc10c9 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -145,6 +145,8 @@ void SDRThread::threadMain() { freq_changed = true; new_freq = command.int_value; break; + default: + break; } } diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index 72b45b5..b813689 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -46,7 +46,7 @@ public: } SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector *data) : - data(data), frequency(frequency), bandwidth(bandwidth) { + frequency(frequency), bandwidth(bandwidth), data(data) { } diff --git a/src/util/GLFont.cpp b/src/util/GLFont.cpp index 4035c30..4fa2bed 100644 --- a/src/util/GLFont.cpp +++ b/src/util/GLFont.cpp @@ -5,7 +5,7 @@ #include GLFontChar::GLFontChar() : - id(0), x(0), y(0), width(0), height(0), xadvance(0), xoffset(0), yoffset(0), index(0), aspect(1) { + id(0), x(0), y(0), width(0), height(0), xoffset(0), yoffset(0), xadvance(0), aspect(1), index(0) { } @@ -96,7 +96,7 @@ int GLFontChar::getIndex() { } GLFont::GLFont() : - numCharacters(0), imageHeight(0), imageWidth(0), base(0), lineHeight(0), texId(0), loaded(false) { + numCharacters(0), lineHeight(0), base(0), imageWidth(0), imageHeight(0), loaded(false), texId(0) { } @@ -289,7 +289,7 @@ void GLFont::loadFont(std::string fontFile) { unsigned int ofs = 0; for (char_i = characters.begin(); char_i != characters.end(); char_i++) { - int charId = (*char_i).first; +// int charId = (*char_i).first; GLFontChar *fchar = (*char_i).second; float faspect = fchar->getAspect(); diff --git a/src/util/MouseTracker.h b/src/util/MouseTracker.h index dad15a3..ed0870f 100644 --- a/src/util/MouseTracker.h +++ b/src/util/MouseTracker.h @@ -5,14 +5,12 @@ class MouseTracker { public: MouseTracker(wxWindow *target) : - target(target), mouseX(0), mouseY(0), lastMouseX(0), lastMouseY(0), originMouseX(0), originMouseY(0), deltaMouseX(0), deltaMouseY(0), isMouseDown( - false), vertDragLock(false), horizDragLock(false), isMouseInView(false) { + mouseX(0), mouseY(0), lastMouseX(0), lastMouseY(0), originMouseX(0), originMouseY(0), deltaMouseX(0), deltaMouseY(0), vertDragLock(false), horizDragLock(false), isMouseDown(false), isMouseInView(false), target(target) { } MouseTracker() : - target(NULL), mouseX(0), mouseY(0), lastMouseX(0), lastMouseY(0), originMouseX(0), originMouseY(0), deltaMouseX(0), deltaMouseY(0), isMouseDown( - false), vertDragLock(false), horizDragLock(false), isMouseInView(false) { + mouseX(0), mouseY(0), lastMouseX(0), lastMouseY(0), originMouseX(0), originMouseY(0), deltaMouseX(0), deltaMouseY(0), vertDragLock(false), horizDragLock(false), isMouseDown(false), isMouseInView(false), target(NULL) { } @@ -43,10 +41,10 @@ public: private: float mouseX, mouseY; float lastMouseX, lastMouseY; - float deltaMouseX, deltaMouseY; float originMouseX, originMouseY; + float deltaMouseX, deltaMouseY; - bool isMouseDown, isMouseInView; bool vertDragLock, horizDragLock; + bool isMouseDown, isMouseInView; wxWindow *target; }; diff --git a/src/util/Timer.cpp b/src/util/Timer.cpp index 4237d42..99ca67a 100644 --- a/src/util/Timer.cpp +++ b/src/util/Timer.cpp @@ -5,7 +5,7 @@ #include #endif -Timer::Timer(void) : time_elapsed(0), system_milliseconds(0), start_time(0), end_time(0), last_update(0), paused_time(0), offset(0), paused_state(false), num_updates(0), lock_state(0), lock_rate(0) +Timer::Timer(void) : time_elapsed(0), system_milliseconds(0), start_time(0), end_time(0), last_update(0), num_updates(0), paused_time(0), offset(0), paused_state(false), lock_state(0), lock_rate(0) { } diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index d9426b5..cc8794d 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -30,8 +30,7 @@ wxEND_EVENT_TABLE() WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - 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) { + wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false) { int in_block_size = FFT_SIZE; int out_block_size = FFT_SIZE; From a7913e32908409c537eb4aac6f45a4e58d881b19 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 23 Dec 2014 01:59:03 -0500 Subject: [PATCH 06/13] refactor remaining transaction objects --- src/AppFrame.cpp | 25 ++++---- src/audio/AudioThread.cpp | 104 +++++++++++++++++++++----------- src/audio/AudioThread.h | 8 +-- src/demod/DemodulatorThread.cpp | 17 +++--- src/demod/DemodulatorThread.h | 2 +- src/sdr/SDRPostThread.cpp | 54 ++++++++--------- src/sdr/SDRPostThread.h | 8 +-- src/sdr/SDRThread.cpp | 11 ++-- src/sdr/SDRThread.h | 6 +- 9 files changed, 130 insertions(+), 105 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index f71556a..50a088c 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -96,14 +96,14 @@ void AppFrame::OnIdle(wxIdleEvent& event) { // std::this_thread::yield(); //#endif if (!wxGetApp().getIQVisualQueue()->empty()) { - SDRThreadIQData iqData; + SDRThreadIQData *iqData; wxGetApp().getIQVisualQueue()->pop(iqData); - if (iqData.data && iqData.data->size()) { - spectrumCanvas->setData(iqData.data); - waterfallCanvas->setData(iqData.data); + if (iqData && iqData->data.size()) { + spectrumCanvas->setData(&iqData->data); + waterfallCanvas->setData(&iqData->data); - delete iqData.data; + delete iqData; } else { std::cout << "Incoming IQ data empty?" << std::endl; } @@ -111,20 +111,19 @@ void AppFrame::OnIdle(wxIdleEvent& event) { } if (!wxGetApp().getAudioVisualQueue()->empty()) { - AudioThreadInput demodAudioData; + AudioThreadInput *demodAudioData; wxGetApp().getAudioVisualQueue()->pop(demodAudioData); - if (demodAudioData.data && demodAudioData.data->size()) { - - if (scopeCanvas->waveform_points.size() != demodAudioData.data->size()*2) { - scopeCanvas->waveform_points.resize(demodAudioData.data->size()*2); + if (demodAudioData && demodAudioData->data.size()) { + 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; + delete demodAudioData; } else { std::cout << "Incoming Demodulator data empty?" << std::endl; } diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 706ce1c..1c55bc9 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -64,44 +64,65 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu continue; } - if (srcmix->currentInput.channels == 0 || !srcmix->currentInput.data) { + if (!srcmix->currentInput) { + if (srcmix->terminated) { + continue; + } + srcmix->inputQueue->pop(srcmix->currentInput); + srcmix->audio_queue_ptr = 0; + continue; + } + + if (srcmix->currentInput->channels == 0 || !srcmix->currentInput->data.size()) { if (!srcmix->inputQueue->empty()) { - if (srcmix->currentInput.data) { - delete srcmix->currentInput.data; + if (srcmix->currentInput) { + delete srcmix->currentInput; + srcmix->currentInput = NULL; + } + if (srcmix->terminated) { + continue; } srcmix->inputQueue->pop(srcmix->currentInput); srcmix->audio_queue_ptr = 0; } - return 0; + continue; } - if (srcmix->currentInput.channels == 1) { + if (srcmix->currentInput->channels == 1) { for (int i = 0; i < nBufferFrames; i++) { - if (srcmix->audio_queue_ptr >= srcmix->currentInput.data->size()) { - if (srcmix->currentInput.data) { - delete srcmix->currentInput.data; + if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) { + if (srcmix->currentInput) { + delete srcmix->currentInput; + srcmix->currentInput = NULL; + } + if (srcmix->terminated) { + continue; } srcmix->inputQueue->pop(srcmix->currentInput); srcmix->audio_queue_ptr = 0; } - if (srcmix->currentInput.data && srcmix->currentInput.data->size()) { - float v = (*srcmix->currentInput.data)[srcmix->audio_queue_ptr] * src->gain; + if (srcmix->currentInput && srcmix->currentInput->data.size()) { + float v = srcmix->currentInput->data[srcmix->audio_queue_ptr] * src->gain; out[i * 2] += v; out[i * 2 + 1] += v; } srcmix->audio_queue_ptr++; } } else { - for (int i = 0, iMax = src->currentInput.channels * nBufferFrames; i < iMax; i++) { - if (srcmix->audio_queue_ptr >= srcmix->currentInput.data->size()) { - if (srcmix->currentInput.data) { - delete srcmix->currentInput.data; + for (int i = 0, iMax = src->currentInput->channels * nBufferFrames; i < iMax; i++) { + if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) { + if (srcmix->currentInput) { + delete srcmix->currentInput; + srcmix->currentInput = NULL; + } + if (srcmix->terminated) { + continue; } srcmix->inputQueue->pop(srcmix->currentInput); srcmix->audio_queue_ptr = 0; } - if (srcmix->currentInput.data && srcmix->currentInput.data->size()) { - out[i] = out[i] + (*srcmix->currentInput.data)[srcmix->audio_queue_ptr] * src->gain; + if (srcmix->currentInput && srcmix->currentInput->data.size()) { + out[i] = out[i] + srcmix->currentInput->data[srcmix->audio_queue_ptr] * src->gain; } srcmix->audio_queue_ptr++; } @@ -122,11 +143,21 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu if (status) { std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl; } + + if (!src->currentInput) { + src->inputQueue->pop(src->currentInput); + src->audio_queue_ptr = 0; + return 0; + } - if (src->currentInput.channels == 0 || !src->currentInput.data) { + if (src->currentInput->channels == 0 || !src->currentInput->data.size()) { if (!src->inputQueue->empty()) { - if (src->currentInput.data) { - delete src->currentInput.data; + if (src->currentInput) { + delete src->currentInput; + src->currentInput = NULL; + } + if (src->terminated) { + return 1; } src->inputQueue->pop(src->currentInput); src->audio_queue_ptr = 0; @@ -134,34 +165,35 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu return 0; } - if (src->currentInput.channels == 1) { + if (src->currentInput->channels == 1) { for (int i = 0; i < nBufferFrames; i++) { - if (src->audio_queue_ptr >= src->currentInput.data->size()) { - if (src->currentInput.data) { - delete src->currentInput.data; + if (src->audio_queue_ptr >= src->currentInput->data.size()) { + if (src->currentInput) { + delete src->currentInput; + src->currentInput = NULL; } if (src->terminated) { - break; + return 1; } src->inputQueue->pop(src->currentInput); src->audio_queue_ptr = 0; } - if (src->currentInput.data && src->currentInput.data->size()) { - out[i * 2] = out[i * 2 + 1] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain; + if (src->currentInput && src->currentInput->data.size()) { + 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()) { + for (int i = 0, iMax = src->currentInput->channels * nBufferFrames; i < iMax; i++) { + if (src->audio_queue_ptr >= src->currentInput->data.size()) { if (src->terminated) { - break; + return 1; } src->inputQueue->pop(src->currentInput); src->audio_queue_ptr = 0; } - if (src->currentInput.data && src->currentInput.data->size()) { - out[i] = (*src->currentInput.data)[src->audio_queue_ptr] * src->gain; + if (src->currentInput && src->currentInput->data.size()) { + out[i] = src->currentInput->data[src->audio_queue_ptr] * src->gain; } src->audio_queue_ptr++; } @@ -321,12 +353,12 @@ bool AudioThread::isActive() { void AudioThread::setActive(bool state) { #ifdef __APPLE__ - AudioThreadInput dummy; + AudioThreadInput *dummy; if (state && !active) { while (!inputQueue->empty()) { // flush queue inputQueue->pop(dummy); - if (dummy.data) { - delete dummy.data; + if (dummy) { + delete dummy; } } deviceController[parameters.deviceId]->bindThread(this); @@ -334,8 +366,8 @@ void AudioThread::setActive(bool state) { deviceController[parameters.deviceId]->removeThread(this); while (!inputQueue->empty()) { // flush queue inputQueue->pop(dummy); - if (dummy.data) { - delete dummy.data; + if (dummy) { + delete dummy; } } } diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index f2446e4..3082f21 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), data(NULL) { + AudioThreadInput(): frequency(0), sampleRate(0), channels(0) { } @@ -32,7 +32,7 @@ public: } - std::vector *data; + std::vector data; }; class AudioThreadCommand { @@ -49,13 +49,13 @@ public: int int_value; }; -typedef ThreadQueue AudioThreadInputQueue; +typedef ThreadQueue AudioThreadInputQueue; typedef ThreadQueue AudioThreadCommandQueue; class AudioThread { public: - AudioThreadInput currentInput; + AudioThreadInput *currentInput; AudioThreadInputQueue *inputQueue; std::atomic audio_queue_ptr; std::atomic underflow_count; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index e66ec78..20826fd 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -76,10 +76,9 @@ void DemodulatorThread::threadMain() { unsigned int num_audio_written; msresamp_rrrf_execute(audio_resampler, demod_output, num_written, resampled_audio_output, &num_audio_written); - AudioThreadInput ati; - ati.channels = 1; - ati.data = new std::vector; - ati.data->assign(resampled_audio_output,resampled_audio_output+num_audio_written); + AudioThreadInput *ati = new AudioThreadInput; + ati->channels = 1; + 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)) { @@ -88,22 +87,20 @@ void DemodulatorThread::threadMain() { } if (visOutQueue != NULL && visOutQueue->empty()) { - AudioThreadInput ati_vis; - ati_vis.channels = ati.channels; + AudioThreadInput *ati_vis = new AudioThreadInput; + ati_vis->channels = ati->channels; int num_vis = DEMOD_VIS_SIZE; if (num_audio_written > num_written) { if (num_vis > num_audio_written) { num_vis = num_audio_written; } - ati_vis.data = new std::vector; - ati_vis.data->assign(ati.data->begin(), ati.data->begin()+num_vis); + 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 = new std::vector; - ati_vis.data->assign(demod_output, demod_output + num_vis); + ati_vis->data.assign(demod_output, demod_output + num_vis); } visOutQueue->push(ati_vis); diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index 5327620..925580d 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -6,7 +6,7 @@ #include "DemodDefs.h" #include "AudioThread.h" -typedef ThreadQueue DemodulatorThreadOutputQueue; +typedef ThreadQueue DemodulatorThreadOutputQueue; #define DEMOD_VIS_SIZE 2048 diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 6f2b84c..70062a8 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -50,25 +50,25 @@ void SDRPostThread::threadMain() { std::cout << "SDR post-processing thread started.." << std::endl; while (!terminated) { - SDRThreadIQData data_in; + SDRThreadIQData *data_in; iqDataInQueue.load()->pop(data_in); - if (data_in.data && data_in.data->size()) { - SDRThreadIQData dataOut; + if (data_in && data_in->data.size()) { + SDRThreadIQData *dataOut = new SDRThreadIQData; - dataOut.frequency = data_in.frequency; - dataOut.bandwidth = data_in.bandwidth; - dataOut.data = data_in.data; + dataOut->frequency = data_in->frequency; + dataOut->bandwidth = data_in->bandwidth; + dataOut->data.assign(data_in->data.begin(), data_in->data.end()); - 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) { @@ -76,9 +76,8 @@ void SDRPostThread::threadMain() { } 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)); + SDRThreadIQData *visualDataOut = new SDRThreadIQData; + visualDataOut->data.assign(dataOut->data.begin(), dataOut->data.begin() + (FFT_SIZE * 2)); iqVisualQueue.load()->push(visualDataOut); } @@ -110,34 +109,32 @@ void SDRPostThread::threadMain() { for (i = demodulators.begin(); i != demodulators.end(); i++) { DemodulatorInstance *demod = *i; - if (demod->getParams().frequency != data_in.frequency - && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { + if (demod->getParams().frequency != data_in->frequency + && abs(data_in->frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { continue; } activeDemods++; } - bool demodActive = false; - if (demodulators.size()) { DemodulatorThreadIQData *demodDataOut = new DemodulatorThreadIQData; - demodDataOut->frequency = data_in.frequency; - demodDataOut->bandwidth = data_in.bandwidth; + demodDataOut->frequency = data_in->frequency; + demodDataOut->bandwidth = data_in->bandwidth; demodDataOut->setRefCount(activeDemods); - demodDataOut->data.assign(dataOut.data->begin(), dataOut.data->begin() + dataOut.data->size()); + demodDataOut->data.assign(dataOut->data.begin(), dataOut->data.begin() + dataOut->data.size()); std::vector::iterator i; for (i = demodulators.begin(); i != demodulators.end(); i++) { DemodulatorInstance *demod = *i; DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod; - if (demod->getParams().frequency != data_in.frequency - && abs(data_in.frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { + if (demod->getParams().frequency != data_in->frequency + && abs(data_in->frequency - demod->getParams().frequency) > (int) ((float) ((float) SRATE / 2.0))) { if (demod->isActive()) { demod->setActive(false); DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData; - dummyDataOut->frequency = data_in.frequency; - dummyDataOut->bandwidth = data_in.bandwidth; + dummyDataOut->frequency = data_in->frequency; + dummyDataOut->bandwidth = data_in->bandwidth; demodQueue->push(dummyDataOut); } } else if (!demod->isActive()) { @@ -157,7 +154,10 @@ void SDRPostThread::threadMain() { } } } - delete dataOut.data; + delete dataOut; + } + if (data_in) { + delete data_in; } } std::cout << "SDR post-processing thread done." << std::endl; @@ -165,6 +165,6 @@ void SDRPostThread::threadMain() { void SDRPostThread::terminate() { terminated = true; - SDRThreadIQData dummy; + SDRThreadIQData *dummy = new SDRThreadIQData; iqDataInQueue.load()->push(dummy); } diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 928cf07..6846aa1 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -13,7 +13,7 @@ public: void setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue); void setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue); - void setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue); + void setIQVisualQueue(SDRThreadIQDataQueue* iqVisQueue); void threadMain(); void terminate(); @@ -21,9 +21,9 @@ public: protected: uint32_t sample_rate; - std::atomic iqDataOutQueue; - std::atomic iqDataInQueue; - std::atomic iqVisualQueue; + std::atomic iqDataOutQueue; + std::atomic iqDataInQueue; + std::atomic iqVisualQueue; std::vector demodulators; std::vector demodulators_add; diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index adc10c9..93dddc4 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -158,20 +158,17 @@ void SDRThread::threadMain() { rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); - std::vector *new_buffer = new std::vector; + SDRThreadIQData *dataOut = new SDRThreadIQData; + dataOut->frequency = frequency; + dataOut->bandwidth = bandwidth; for (int i = 0; i < n_read; i++) { - new_buffer->push_back(buf[i] - 127); + dataOut->data.push_back(buf[i] - 127); } double time_slice = (double) n_read / (double) sample_rate; seconds += time_slice; - SDRThreadIQData dataOut; - dataOut.frequency = frequency; - dataOut.bandwidth = bandwidth; - dataOut.data = new_buffer; - if (iqDataOutQueue != NULL) { iqDataOutQueue.load()->push(dataOut); } diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index b813689..b917160 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -38,7 +38,7 @@ class SDRThreadIQData { public: unsigned int frequency; unsigned int bandwidth; - std::vector *data; + std::vector data; SDRThreadIQData() : frequency(0), bandwidth(0), data(NULL) { @@ -46,7 +46,7 @@ public: } SDRThreadIQData(unsigned int bandwidth, unsigned int frequency, std::vector *data) : - frequency(frequency), bandwidth(bandwidth), data(data) { + frequency(frequency), bandwidth(bandwidth) { } @@ -56,7 +56,7 @@ public: }; typedef ThreadQueue SDRThreadCommandQueue; -typedef ThreadQueue SDRThreadIQDataQueue; +typedef ThreadQueue SDRThreadIQDataQueue; class SDRThread { public: From d53eb5fc9f3eed91f7dce2e76a0858ee80b5f54d Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 23 Dec 2014 02:01:41 -0500 Subject: [PATCH 07/13] shift key for faster frequency change --- src/visual/WaterfallCanvas.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index d9426b5..c1f0ae4 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -163,13 +163,21 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { switch (event.GetKeyCode()) { case WXK_RIGHT: freq = wxGetApp().getFrequency(); - freq += SRATE / 2; + if (shiftDown) { + freq += SRATE*10; + } else { + freq += SRATE / 2; + } wxGetApp().setFrequency(freq); ((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq)); break; case WXK_LEFT: freq = wxGetApp().getFrequency(); - freq -= SRATE / 2; + if (shiftDown) { + freq -= SRATE*10; + } else { + freq -= SRATE / 2; + } wxGetApp().setFrequency(freq); ((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq)); break; From ef78ffc6f3bf5fc7d422ce528f4bb36442dbdac2 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 23 Dec 2014 02:32:25 -0500 Subject: [PATCH 08/13] minor warning fixes --- src/audio/AudioThread.cpp | 2 +- src/sdr/SDRThread.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 1c55bc9..9a4cbf2 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -10,7 +10,7 @@ std::map AudioThread::deviceThread; #endif AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) : -inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify(threadQueueNotify) { +currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify(threadQueueNotify) { #ifdef __APPLE__ boundThreads = new std::vector; #endif diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index b917160..b2a59ed 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -41,7 +41,7 @@ public: std::vector data; SDRThreadIQData() : - frequency(0), bandwidth(0), data(NULL) { + frequency(0), bandwidth(0) { } From b7375ce09f06f1daa95ae933704ff0fcdcbf2e66 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 23 Dec 2014 23:37:18 -0500 Subject: [PATCH 09/13] Threading crash fixes, reusable IQ buffer queue --- src/demod/DemodDefs.h | 2 ++ src/demod/DemodulatorPreThread.cpp | 7 +++--- src/sdr/SDRPostThread.cpp | 34 +++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index e6cf822..958421d 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -5,6 +5,7 @@ #include "liquid/liquid.h" #include +#include enum DemodulatorType { DEMOD_TYPE_NULL, @@ -60,6 +61,7 @@ public: unsigned int frequency; unsigned int bandwidth; std::vector data; + mutable std::mutex m_mutex; DemodulatorThreadIQData() : frequency(0), bandwidth(0), refCount(0) { diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 8e70537..20e84e1 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -157,6 +157,7 @@ void DemodulatorPreThread::threadMain() { continue; } + std::lock_guard < std::mutex > lock(inp->m_mutex); std::vector *data = &inp->data; if (data->size()) { int bufSize = data->size() / 2; @@ -173,6 +174,8 @@ void DemodulatorPreThread::threadMain() { in_buf[i].imag = (float) (*data)[i * 2 + 1] / 127.0f; } + inp->decRefCount(); + if (shift_freq != 0) { if (shift_freq < 0) { nco_crcf_mix_block_up(nco_shift, in_buf, out_buf, bufSize); @@ -195,10 +198,8 @@ void DemodulatorPreThread::threadMain() { resamp->resampler = resampler; postInputQueue->push(resamp); + } else { inp->decRefCount(); - if (inp->getRefCount()<=0) { - delete inp; - } } if (!workerResults->empty()) { diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 70062a8..07b9353 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -1,8 +1,10 @@ #include "SDRPostThread.h" #include "CubicSDRDefs.h" -#include #include "CubicSDR.h" +#include +#include + SDRPostThread::SDRPostThread() : sample_rate(SRATE), iqDataOutQueue(NULL), iqDataInQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL) { } @@ -49,6 +51,9 @@ void SDRPostThread::threadMain() { std::cout << "SDR post-processing thread started.." << std::endl; + std::deque buffers; + std::deque::iterator buffers_i; + while (!terminated) { SDRThreadIQData *data_in; @@ -117,7 +122,22 @@ void SDRPostThread::threadMain() { } if (demodulators.size()) { - DemodulatorThreadIQData *demodDataOut = new DemodulatorThreadIQData; + + DemodulatorThreadIQData *demodDataOut = NULL; + + for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { + if ((*buffers_i)->getRefCount() <= 0) { + demodDataOut = (*buffers_i); + break; + } + } + + if (demodDataOut == NULL) { + demodDataOut = new DemodulatorThreadIQData; + buffers.push_back(demodDataOut); + } + + std::lock_guard < std::mutex > lock(demodDataOut->m_mutex); demodDataOut->frequency = data_in->frequency; demodDataOut->bandwidth = data_in->bandwidth; demodDataOut->setRefCount(activeDemods); @@ -150,7 +170,7 @@ void SDRPostThread::threadMain() { } if (!pushedData) { - delete demodDataOut; + demodDataOut->setRefCount(0); } } } @@ -160,6 +180,14 @@ void SDRPostThread::threadMain() { delete data_in; } } + + while (!buffers.empty()) { + DemodulatorThreadIQData *demodDataDel = buffers.front(); + buffers.pop_front(); + std::lock_guard < std::mutex > lock(demodDataDel->m_mutex); + delete demodDataDel; + } + std::cout << "SDR post-processing thread done." << std::endl; } From 8c852ed491a99de9b0beee9681ee14b63f7e1313 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 24 Dec 2014 00:11:41 -0500 Subject: [PATCH 10/13] SDR thread reusable buffers implemented --- src/CubicSDRDefs.h | 22 ++++++++++++++++++++++ src/audio/AudioThread.h | 5 ++--- src/demod/DemodDefs.h | 24 ++++-------------------- src/sdr/SDRPostThread.cpp | 5 ++--- src/sdr/SDRThread.cpp | 39 +++++++++++++++++++++++++++++++++++---- src/sdr/SDRThread.h | 2 +- 6 files changed, 66 insertions(+), 31 deletions(-) diff --git a/src/CubicSDRDefs.h b/src/CubicSDRDefs.h index d54cf73..7a8bb8e 100644 --- a/src/CubicSDRDefs.h +++ b/src/CubicSDRDefs.h @@ -11,3 +11,25 @@ #define DEFAULT_FREQ 98900000 #define AUDIO_FREQUENCY 44100 + +#include +#include + +class ReferenceCounter { +public: + mutable std::mutex m_mutex; + + void setRefCount(int rc) { + refCount.store(rc); + } + + void decRefCount() { + refCount.store(refCount.load()-1); + } + + int getRefCount() { + return refCount.load(); + } +protected: + std::atomic refCount; +}; diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 3082f21..444e9c0 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -18,11 +18,12 @@ #include "RtAudio.h" #include "DemodDefs.h" -class AudioThreadInput { +class AudioThreadInput: public ReferenceCounter { public: int frequency; int sampleRate; int channels; + std::vector data; AudioThreadInput(): frequency(0), sampleRate(0), channels(0) { @@ -31,8 +32,6 @@ public: ~AudioThreadInput() { } - - std::vector data; }; class AudioThreadCommand { diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 958421d..634268c 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -56,39 +56,23 @@ public: DemodulatorThreadControlCommandEnum cmd; }; -class DemodulatorThreadIQData { +class DemodulatorThreadIQData : public ReferenceCounter { public: unsigned int frequency; unsigned int bandwidth; std::vector data; - mutable std::mutex m_mutex; DemodulatorThreadIQData() : - frequency(0), bandwidth(0), refCount(0) { + frequency(0), bandwidth(0) { } - void setRefCount(int rc) { - refCount.store(rc); - } - - void decRefCount() { - refCount.store(refCount.load()-1); - } - - int getRefCount() { - return refCount.load(); - } - ~DemodulatorThreadIQData() { } -private: - std::atomic refCount; - }; -class DemodulatorThreadPostIQData { +class DemodulatorThreadPostIQData : public ReferenceCounter { public: std::vector data; float audio_resample_ratio; @@ -106,7 +90,7 @@ public: }; -class DemodulatorThreadAudioData { +class DemodulatorThreadAudioData : public ReferenceCounter { public: unsigned int frequency; unsigned int sampleRate; diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 07b9353..a3aa4ce 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -58,6 +58,7 @@ void SDRPostThread::threadMain() { SDRThreadIQData *data_in; iqDataInQueue.load()->pop(data_in); +// std::lock_guard < std::mutex > lock(data_in->m_mutex); if (data_in && data_in->data.size()) { SDRThreadIQData *dataOut = new SDRThreadIQData; @@ -176,9 +177,7 @@ void SDRPostThread::threadMain() { } delete dataOut; } - if (data_in) { - delete data_in; - } + data_in->decRefCount(); } while (!buffers.empty()) { diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index 93dddc4..0d88944 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -91,7 +91,7 @@ int SDRThread::enumerate_rtl() { void SDRThread::threadMain() { #ifdef __APPLE__ pthread_t tID = pthread_self(); // ID of this thread - int priority = sched_get_priority_max( SCHED_FIFO )-1; + int priority = sched_get_priority_max( SCHED_FIFO) - 1; sched_param prio = { priority }; // scheduling priority of thread pthread_setschedparam(tID, SCHED_FIFO, &prio); #endif @@ -128,6 +128,10 @@ void SDRThread::threadMain() { double seconds = 0.0; std::cout << "SDR thread started.." << std::endl; + + std::deque buffers; + std::deque::iterator buffers_i; + while (!terminated) { SDRThreadCommandQueue *cmdQueue = m_pQueue.load(); @@ -145,7 +149,7 @@ void SDRThread::threadMain() { freq_changed = true; new_freq = command.int_value; break; - default: + default: break; } } @@ -158,12 +162,31 @@ void SDRThread::threadMain() { rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); - SDRThreadIQData *dataOut = new SDRThreadIQData; + SDRThreadIQData *dataOut = NULL; + + for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { + if ((*buffers_i)->getRefCount() <= 0) { + dataOut = (*buffers_i); + break; + } + } + + if (dataOut == NULL) { + dataOut = new SDRThreadIQData; + buffers.push_back(dataOut); + } + + std::lock_guard < std::mutex > lock(dataOut->m_mutex); + dataOut->setRefCount(1); dataOut->frequency = frequency; dataOut->bandwidth = bandwidth; + if (dataOut->data.size() != n_read) { + dataOut->data.resize(n_read); + } + for (int i = 0; i < n_read; i++) { - dataOut->data.push_back(buf[i] - 127); + dataOut->data[i] = buf[i] - 127; } double time_slice = (double) n_read / (double) sample_rate; @@ -173,6 +196,14 @@ void SDRThread::threadMain() { iqDataOutQueue.load()->push(dataOut); } } + + while (!buffers.empty()) { + SDRThreadIQData *iqDataDel = buffers.front(); + buffers.pop_front(); + std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); + delete iqDataDel; + } + std::cout << "SDR thread done." << std::endl; } diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index b2a59ed..8c9ad26 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -34,7 +34,7 @@ public: int int_value; }; -class SDRThreadIQData { +class SDRThreadIQData : public ReferenceCounter { public: unsigned int frequency; unsigned int bandwidth; From 576a77e09544f105d3dc588f4866b355aa8422d5 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 24 Dec 2014 01:28:33 -0500 Subject: [PATCH 11/13] Update remaining buffers, cleanup --- src/audio/AudioThread.cpp | 21 +++++--- src/audio/AudioThread.h | 5 +- src/demod/DemodDefs.h | 83 +++++++++++++---------------- src/demod/DemodulatorInstance.cpp | 9 ++-- src/demod/DemodulatorInstance.h | 9 +--- src/demod/DemodulatorPreThread.cpp | 40 +++++++++++--- src/demod/DemodulatorPreThread.h | 1 - src/demod/DemodulatorThread.cpp | 50 +++++++++++++---- src/demod/DemodulatorThread.h | 6 +-- src/demod/DemodulatorWorkerThread.h | 8 +-- src/sdr/SDRPostThread.cpp | 16 +++--- src/sdr/SDRThread.cpp | 8 +-- src/visual/WaterfallCanvas.cpp | 13 +++-- 13 files changed, 159 insertions(+), 110 deletions(-) diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 9a4cbf2..de94c66 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -10,7 +10,8 @@ std::map AudioThread::deviceThread; #endif AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) : -currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify(threadQueueNotify) { + currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify( + threadQueueNotify) { #ifdef __APPLE__ boundThreads = new std::vector; #endif @@ -72,11 +73,13 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu srcmix->audio_queue_ptr = 0; continue; } - + + std::lock_guard < std::mutex > lock(srcmix->currentInput->m_mutex); + if (srcmix->currentInput->channels == 0 || !srcmix->currentInput->data.size()) { if (!srcmix->inputQueue->empty()) { if (srcmix->currentInput) { - delete srcmix->currentInput; + srcmix->currentInput->decRefCount(); srcmix->currentInput = NULL; } if (srcmix->terminated) { @@ -92,7 +95,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu for (int i = 0; i < nBufferFrames; i++) { if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) { if (srcmix->currentInput) { - delete srcmix->currentInput; + srcmix->currentInput->decRefCount(); srcmix->currentInput = NULL; } if (srcmix->terminated) { @@ -112,7 +115,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu for (int i = 0, iMax = src->currentInput->channels * nBufferFrames; i < iMax; i++) { if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) { if (srcmix->currentInput) { - delete srcmix->currentInput; + srcmix->currentInput->decRefCount(); srcmix->currentInput = NULL; } if (srcmix->terminated) { @@ -143,17 +146,19 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu if (status) { std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl; } - + if (!src->currentInput) { src->inputQueue->pop(src->currentInput); src->audio_queue_ptr = 0; return 0; } + std::lock_guard < std::mutex > lock(src->currentInput->m_mutex); + if (src->currentInput->channels == 0 || !src->currentInput->data.size()) { if (!src->inputQueue->empty()) { if (src->currentInput) { - delete src->currentInput; + src->currentInput->decRefCount(); src->currentInput = NULL; } if (src->terminated) { @@ -169,7 +174,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu for (int i = 0; i < nBufferFrames; i++) { if (src->audio_queue_ptr >= src->currentInput->data.size()) { if (src->currentInput) { - delete src->currentInput; + src->currentInput->decRefCount(); src->currentInput = NULL; } if (src->terminated) { diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 444e9c0..da411b3 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -18,14 +18,15 @@ #include "RtAudio.h" #include "DemodDefs.h" -class AudioThreadInput: public ReferenceCounter { +class AudioThreadInput: public ReferenceCounter { public: int frequency; int sampleRate; int channels; std::vector data; - AudioThreadInput(): frequency(0), sampleRate(0), channels(0) { + AudioThreadInput() : + frequency(0), sampleRate(0), channels(0) { } diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 634268c..29d8d05 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -8,10 +8,7 @@ #include enum DemodulatorType { - DEMOD_TYPE_NULL, - DEMOD_TYPE_AM, - DEMOD_TYPE_FM, - DEMOD_TYPE_LSB, DEMOD_TYPE_USB + DEMOD_TYPE_NULL, DEMOD_TYPE_AM, DEMOD_TYPE_FM, DEMOD_TYPE_LSB, DEMOD_TYPE_USB }; class DemodulatorThread; @@ -34,19 +31,17 @@ public: DemodulatorThreadCommand(DemodulatorThreadCommandEnum cmd) : cmd(cmd), context(NULL), int_value(0) { - } + } - DemodulatorThreadCommandEnum cmd; - void *context; - int int_value; + DemodulatorThreadCommandEnum cmd; + void *context; + int int_value; }; class DemodulatorThreadControlCommand { public: enum DemodulatorThreadControlCommandEnum { - DEMOD_THREAD_CMD_CTL_NULL, - DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO, - DEMOD_THREAD_CMD_CTL_SQUELCH_OFF + DEMOD_THREAD_CMD_CTL_NULL, DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO, DEMOD_THREAD_CMD_CTL_SQUELCH_OFF }; DemodulatorThreadControlCommand() : @@ -56,62 +51,61 @@ public: DemodulatorThreadControlCommandEnum cmd; }; -class DemodulatorThreadIQData : public ReferenceCounter { +class DemodulatorThreadIQData: public ReferenceCounter { public: - unsigned int frequency; - unsigned int bandwidth; - std::vector data; + unsigned int frequency; + unsigned int bandwidth; + std::vector data; - DemodulatorThreadIQData() : - frequency(0), bandwidth(0) { + DemodulatorThreadIQData() : + frequency(0), bandwidth(0) { - } + } - ~DemodulatorThreadIQData() { + ~DemodulatorThreadIQData() { - } + } }; -class DemodulatorThreadPostIQData : public ReferenceCounter { +class DemodulatorThreadPostIQData: public ReferenceCounter { public: - std::vector data; - float audio_resample_ratio; - msresamp_rrrf audio_resampler; + 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) { - } + } - ~DemodulatorThreadPostIQData() { + ~DemodulatorThreadPostIQData() { - } + } }; - -class DemodulatorThreadAudioData : public ReferenceCounter { +class DemodulatorThreadAudioData: public ReferenceCounter { public: - unsigned int frequency; - unsigned int sampleRate; - unsigned char channels; + unsigned int frequency; + unsigned int sampleRate; + unsigned char channels; - std::vector *data; + std::vector *data; - DemodulatorThreadAudioData() : - frequency(0), sampleRate(0), channels(0), data(NULL) { + DemodulatorThreadAudioData() : + frequency(0), sampleRate(0), channels(0), data(NULL) { - } + } - DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, - std::vector *data) : - frequency(frequency), sampleRate(sampleRate), channels(1), data(data) { + DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, std::vector *data) : + frequency(frequency), sampleRate(sampleRate), channels(1), data(data) { - } + } - ~DemodulatorThreadAudioData() { + ~DemodulatorThreadAudioData() { - } + } }; typedef ThreadQueue DemodulatorThreadInputQueue; @@ -119,7 +113,6 @@ typedef ThreadQueue DemodulatorThreadPostInputQue typedef ThreadQueue DemodulatorThreadCommandQueue; typedef ThreadQueue DemodulatorThreadControlCommandQueue; - class DemodulatorThreadParameters { public: unsigned int frequency; @@ -131,7 +124,7 @@ public: DemodulatorThreadParameters() : frequency(0), inputRate(SRATE), bandwidth(200000), audioSampleRate( - AUDIO_FREQUENCY), demodType(DEMOD_TYPE_FM) { + AUDIO_FREQUENCY), demodType(DEMOD_TYPE_FM) { } diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index 9d46565..ab26849 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -77,12 +77,12 @@ DemodulatorThreadParameters &DemodulatorInstance::getParams() { } void DemodulatorInstance::terminate() { - std::cout << "Terminating demodulator preprocessor thread.." << std::endl; - demodulatorPreThread->terminate(); - std::cout << "Terminating demodulator thread.." << std::endl; - demodulatorThread->terminate(); std::cout << "Terminating demodulator audio thread.." << std::endl; audioThread->terminate(); + std::cout << "Terminating demodulator thread.." << std::endl; + demodulatorThread->terminate(); + std::cout << "Terminating demodulator preprocessor thread.." << std::endl; + demodulatorPreThread->terminate(); } std::string DemodulatorInstance::getLabel() { @@ -146,7 +146,6 @@ void DemodulatorInstance::setActive(bool state) { audioThread->setActive(state); } - void DemodulatorInstance::squelchAuto() { DemodulatorThreadControlCommand command; command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO; diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index ccd14be..2853d6c 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -49,16 +49,11 @@ public: bool isActive(); void setActive(bool state); - void squelchAuto(); - bool isSquelchEnabled(); + void squelchAuto();bool isSquelchEnabled(); void setSquelchEnabled(bool state); private: - std::atomic label; - bool terminated; - bool demodTerminated; - bool audioTerminated; - bool preDemodTerminated; + std::atomic label;bool terminated;bool demodTerminated;bool audioTerminated;bool preDemodTerminated; std::atomic active; std::atomic squelch; }; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 20e84e1..4e5691d 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -10,7 +10,8 @@ DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* pQueueIn, DemodulatorThreadPostInputQueue* pQueueOut, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : inputQueue(pQueueIn), postInputQueue(pQueueOut), terminated(false), initialized(false), audio_resampler(NULL), resample_ratio(1), audio_resample_ratio( - 1), resampler(NULL), commandQueue(NULL), fir_filter(NULL), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl) { + 1), resampler(NULL), commandQueue(NULL), fir_filter(NULL), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl( + threadQueueControl) { float kf = 0.5; // modulation factor fdem = freqdem_create(kf); @@ -90,7 +91,7 @@ void DemodulatorPreThread::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 @@ -99,6 +100,10 @@ void DemodulatorPreThread::threadMain() { } std::cout << "Demodulator preprocessor thread started.." << std::endl; + + std::deque buffers; + std::deque::iterator buffers_i; + while (!terminated) { DemodulatorThreadIQData *inp; inputQueue->pop(inp); @@ -157,7 +162,7 @@ void DemodulatorPreThread::threadMain() { continue; } - std::lock_guard < std::mutex > lock(inp->m_mutex); +// std::lock_guard < std::mutex > lock(inp->m_mutex); std::vector *data = &inp->data; if (data->size()) { int bufSize = data->size() / 2; @@ -174,8 +179,6 @@ void DemodulatorPreThread::threadMain() { in_buf[i].imag = (float) (*data)[i * 2 + 1] / 127.0f; } - inp->decRefCount(); - if (shift_freq != 0) { if (shift_freq < 0) { nco_crcf_mix_block_up(nco_shift, in_buf, out_buf, bufSize); @@ -187,8 +190,22 @@ void DemodulatorPreThread::threadMain() { out_buf = temp_buf; } - DemodulatorThreadPostIQData *resamp = new DemodulatorThreadPostIQData; - resamp->data.assign(in_buf,in_buf+bufSize); + DemodulatorThreadPostIQData *resamp = NULL; + + for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { + if ((*buffers_i)->getRefCount() <= 0) { + resamp = (*buffers_i); + break; + } + } + + if (resamp == NULL) { + resamp = new DemodulatorThreadPostIQData; + buffers.push_back(resamp); + } + + resamp->setRefCount(1); + resamp->data.assign(in_buf, in_buf + bufSize); // firfilt_crcf_execute_block(fir_filter, in_buf, bufSize, &((*resamp.data)[0])); @@ -198,6 +215,8 @@ void DemodulatorPreThread::threadMain() { resamp->resampler = resampler; postInputQueue->push(resamp); + + inp->decRefCount(); } else { inp->decRefCount(); } @@ -230,6 +249,13 @@ void DemodulatorPreThread::threadMain() { } } + while (!buffers.empty()) { + DemodulatorThreadPostIQData *iqDataDel = buffers.front(); + buffers.pop_front(); + std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); + delete iqDataDel; + } + std::cout << "Demodulator preprocessor thread done." << std::endl; DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED); tCmd.context = this; diff --git a/src/demod/DemodulatorPreThread.h b/src/demod/DemodulatorPreThread.h index 0295984..95304da 100644 --- a/src/demod/DemodulatorPreThread.h +++ b/src/demod/DemodulatorPreThread.h @@ -32,7 +32,6 @@ public: threadQueueControl = tQueue; } - DemodulatorThreadParameters &getParams() { return params; } diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 20826fd..925af72 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -6,8 +6,10 @@ #include #endif -DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : - postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), terminated(false), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelch_level(0), squelch_tolerance(0), squelch_enabled(false) { +DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, + DemodulatorThreadCommandQueue* threadQueueNotify) : + postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), terminated(false), threadQueueNotify(threadQueueNotify), threadQueueControl( + threadQueueControl), squelch_level(0), squelch_tolerance(0), squelch_enabled(false) { float kf = 0.5; // modulation factor fdem = freqdem_create(kf); @@ -35,14 +37,19 @@ void DemodulatorThread::threadMain() { agc_crcf_set_bandwidth(agc, 1e-3f); std::cout << "Demodulator thread started.." << std::endl; + + std::deque buffers; + std::deque::iterator buffers_i; + while (!terminated) { DemodulatorThreadPostIQData *inp; postInputQueue->pop(inp); + std::lock_guard < std::mutex > lock(inp->m_mutex); int bufSize = inp->data.size(); if (!bufSize) { - delete inp; + inp->decRefCount(); continue; } @@ -76,26 +83,40 @@ void DemodulatorThread::threadMain() { unsigned int num_audio_written; msresamp_rrrf_execute(audio_resampler, demod_output, num_written, resampled_audio_output, &num_audio_written); - AudioThreadInput *ati = new AudioThreadInput; - ati->channels = 1; - 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)) { + AudioThreadInput *ati = NULL; + + for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { + if ((*buffers_i)->getRefCount() <= 0) { + ati = (*buffers_i); + break; + } + } + + if (ati == NULL) { + ati = new AudioThreadInput; + buffers.push_back(ati); + } + + ati->setRefCount(1); + ati->channels = 1; + ati->data.assign(resampled_audio_output, resampled_audio_output + num_audio_written); + audioInputQueue->push(ati); } } if (visOutQueue != NULL && visOutQueue->empty()) { AudioThreadInput *ati_vis = new AudioThreadInput; - ati_vis->channels = ati->channels; + ati_vis->channels = 1; int num_vis = DEMOD_VIS_SIZE; if (num_audio_written > num_written) { 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.assign(resampled_audio_output, resampled_audio_output + num_vis); } else { if (num_vis > num_written) { num_vis = num_written; @@ -115,7 +136,7 @@ void DemodulatorThread::threadMain() { switch (command.cmd) { case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO: squelch_level = agc_crcf_get_signal_level(agc); - squelch_tolerance = agc_crcf_get_signal_level(agc)/2.0; + squelch_tolerance = agc_crcf_get_signal_level(agc) / 2.0; squelch_enabled = true; break; case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_OFF: @@ -129,7 +150,7 @@ void DemodulatorThread::threadMain() { } } - delete inp; + inp->decRefCount(); } if (resampler != NULL) { @@ -141,6 +162,13 @@ void DemodulatorThread::threadMain() { agc_crcf_destroy(agc); + while (!buffers.empty()) { + AudioThreadInput *audioDataDel = buffers.front(); + buffers.pop_front(); + std::lock_guard < std::mutex > lock(audioDataDel->m_mutex); + delete audioDataDel; + } + std::cout << "Demodulator thread done." << std::endl; DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED); tCmd.context = this; diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index 925580d..3fb4bf6 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -13,7 +13,8 @@ typedef ThreadQueue DemodulatorThreadOutputQueue; class DemodulatorThread { public: - DemodulatorThread(DemodulatorThreadPostInputQueue* pQueueIn, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify); + DemodulatorThread(DemodulatorThreadPostInputQueue* pQueueIn, DemodulatorThreadControlCommandQueue *threadQueueControl, + DemodulatorThreadCommandQueue* threadQueueNotify); ~DemodulatorThread(); #ifdef __APPLE__ @@ -53,6 +54,5 @@ protected: DemodulatorThreadCommandQueue* threadQueueNotify; DemodulatorThreadControlCommandQueue *threadQueueControl; float squelch_level; - float squelch_tolerance; - bool squelch_enabled; + float squelch_tolerance;bool squelch_enabled; }; diff --git a/src/demod/DemodulatorWorkerThread.h b/src/demod/DemodulatorWorkerThread.h index 8edcec2..8db4c5a 100644 --- a/src/demod/DemodulatorWorkerThread.h +++ b/src/demod/DemodulatorWorkerThread.h @@ -22,14 +22,14 @@ public: }; DemodulatorWorkerThreadResult() : - cmd(DEMOD_WORKER_THREAD_RESULT_NULL), fir_filter(NULL), resampler(NULL), resample_ratio( - 0), audio_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth(0), audioSampleRate(0) { + cmd(DEMOD_WORKER_THREAD_RESULT_NULL), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio( + 0), inputRate(0), bandwidth(0), audioSampleRate(0) { } DemodulatorWorkerThreadResult(DemodulatorThreadResultEnum cmd) : - cmd(cmd), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio( - 0), inputRate(0), bandwidth(0), audioSampleRate(0) { + cmd(cmd), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth( + 0), audioSampleRate(0) { } diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index a3aa4ce..b80c5da 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -41,7 +41,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 @@ -123,22 +123,22 @@ void SDRPostThread::threadMain() { } if (demodulators.size()) { - + DemodulatorThreadIQData *demodDataOut = NULL; - + for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { if ((*buffers_i)->getRefCount() <= 0) { demodDataOut = (*buffers_i); break; } } - + if (demodDataOut == NULL) { demodDataOut = new DemodulatorThreadIQData; buffers.push_back(demodDataOut); } - - std::lock_guard < std::mutex > lock(demodDataOut->m_mutex); + +// std::lock_guard < std::mutex > lock(demodDataOut->m_mutex); demodDataOut->frequency = data_in->frequency; demodDataOut->bandwidth = data_in->bandwidth; demodDataOut->setRefCount(activeDemods); @@ -183,8 +183,8 @@ void SDRPostThread::threadMain() { while (!buffers.empty()) { DemodulatorThreadIQData *demodDataDel = buffers.front(); buffers.pop_front(); - std::lock_guard < std::mutex > lock(demodDataDel->m_mutex); - delete demodDataDel; +// std::lock_guard < std::mutex > lock(demodDataDel->m_mutex); +// delete demodDataDel; } std::cout << "SDR post-processing thread done." << std::endl; diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index 0d88944..b52f960 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -92,7 +92,7 @@ void SDRThread::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 @@ -176,7 +176,7 @@ void SDRThread::threadMain() { buffers.push_back(dataOut); } - std::lock_guard < std::mutex > lock(dataOut->m_mutex); +// std::lock_guard < std::mutex > lock(dataOut->m_mutex); dataOut->setRefCount(1); dataOut->frequency = frequency; dataOut->bandwidth = bandwidth; @@ -200,8 +200,8 @@ void SDRThread::threadMain() { while (!buffers.empty()) { SDRThreadIQData *iqDataDel = buffers.front(); buffers.pop_front(); - std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); - delete iqDataDel; +// std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); +// delete iqDataDel; } std::cout << "SDR thread done." << std::endl; diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 685cf3c..1b82be2 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -30,7 +30,8 @@ wxEND_EVENT_TABLE() WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false) { + wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState( + WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false) { int in_block_size = FFT_SIZE; int out_block_size = FFT_SIZE; @@ -76,7 +77,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { DemodulatorInstance *activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator(); DemodulatorInstance *lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator(); - bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); + bool isNew = shiftDown + || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); if (mTracker.mouseInView()) { if (nextDragState == WF_DRAG_RANGE) { @@ -163,7 +165,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { case WXK_RIGHT: freq = wxGetApp().getFrequency(); if (shiftDown) { - freq += SRATE*10; + freq += SRATE * 10; } else { freq += SRATE / 2; } @@ -173,7 +175,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { case WXK_LEFT: freq = wxGetApp().getFrequency(); if (shiftDown) { - freq -= SRATE*10; + freq -= SRATE * 10; } else { freq -= SRATE / 2; } @@ -438,7 +440,8 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) { altDown = event.AltDown(); ctrlDown = event.ControlDown(); - bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); + bool isNew = shiftDown + || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); mTracker.setVertDragLock(false); mTracker.setHorizDragLock(false); From b487cf99012ae4eca39ed66d52d889f1fe1e30ee Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 24 Dec 2014 03:03:34 -0500 Subject: [PATCH 12/13] convert inline buffers to dynamic growth per instance --- src/demod/DemodulatorPreThread.cpp | 23 +++++++++------ src/demod/DemodulatorThread.cpp | 46 +++++++++++++++++++++++------- src/sdr/SDRPostThread.cpp | 31 +++++++++++--------- src/sdr/SDRThread.cpp | 4 +++ 4 files changed, 72 insertions(+), 32 deletions(-) diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 4e5691d..f0e26d4 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -104,6 +104,9 @@ void DemodulatorPreThread::threadMain() { std::deque buffers; std::deque::iterator buffers_i; + std::vector in_buf_data; + std::vector out_buf_data; + while (!terminated) { DemodulatorThreadIQData *inp; inputQueue->pop(inp); @@ -167,11 +170,17 @@ void DemodulatorPreThread::threadMain() { if (data->size()) { int bufSize = data->size() / 2; - liquid_float_complex in_buf_data[bufSize]; - liquid_float_complex out_buf_data[bufSize]; + if (in_buf_data.size() != bufSize) { + if (in_buf_data.capacity() < bufSize) { + in_buf_data.reserve(bufSize); + out_buf_data.reserve(bufSize); + } + in_buf_data.resize(bufSize); + out_buf_data.resize(bufSize); + } - liquid_float_complex *in_buf = in_buf_data; - liquid_float_complex *out_buf = out_buf_data; + liquid_float_complex *in_buf = &in_buf_data[0]; + liquid_float_complex *out_buf = &out_buf_data[0]; liquid_float_complex *temp_buf = NULL; for (int i = 0; i < bufSize; i++) { @@ -215,12 +224,10 @@ void DemodulatorPreThread::threadMain() { resamp->resampler = resampler; postInputQueue->push(resamp); - - inp->decRefCount(); - } else { - inp->decRefCount(); } + inp->decRefCount(); + if (!workerResults->empty()) { while (!workerResults->empty()) { DemodulatorWorkerThreadResult result; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 925af72..8b4f7ea 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -41,6 +41,11 @@ void DemodulatorThread::threadMain() { std::deque buffers; std::deque::iterator buffers_i; + std::vector resampled_data; + std::vector agc_data; + std::vector demod_output; + std::vector resampled_audio_output; + while (!terminated) { DemodulatorThreadPostIQData *inp; postInputQueue->pop(inp); @@ -64,24 +69,43 @@ void DemodulatorThread::threadMain() { } int out_size = ceil((float) (bufSize) * inp->resample_ratio); - liquid_float_complex resampled_data[out_size]; - liquid_float_complex agc_data[out_size]; + + if (agc_data.size() != out_size) { + if (agc_data.capacity() < out_size) { + agc_data.reserve(out_size); + resampled_data.reserve(out_size); + } + agc_data.resize(out_size); + resampled_data.resize(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[0], &num_written); - agc_crcf_execute_block(agc, resampled_data, num_written, agc_data); + agc_crcf_execute_block(agc, &resampled_data[0], num_written, &agc_data[0]); float audio_resample_ratio = inp->audio_resample_ratio; - float demod_output[num_written]; - freqdem_demodulate_block(fdem, agc_data, num_written, demod_output); + if (demod_output.size() != num_written) { + if (demod_output.capacity() < num_written) { + demod_output.reserve(num_written); + } + demod_output.resize(num_written); + } + + freqdem_demodulate_block(fdem, &agc_data[0], num_written, &demod_output[0]); int audio_out_size = ceil((float) (num_written) * audio_resample_ratio); - float resampled_audio_output[audio_out_size]; + + if (audio_out_size != resampled_audio_output.size()) { + if (resampled_audio_output.capacity() < audio_out_size) { + resampled_audio_output.reserve(audio_out_size); + } + resampled_audio_output.resize(audio_out_size); + } unsigned int num_audio_written; - msresamp_rrrf_execute(audio_resampler, demod_output, num_written, resampled_audio_output, &num_audio_written); + msresamp_rrrf_execute(audio_resampler, &demod_output[0], num_written, &resampled_audio_output[0], &num_audio_written); if (audioInputQueue != NULL) { if (!squelch_enabled || ((agc_crcf_get_signal_level(agc)) >= 0.1)) { @@ -101,7 +125,7 @@ void DemodulatorThread::threadMain() { ati->setRefCount(1); ati->channels = 1; - ati->data.assign(resampled_audio_output, resampled_audio_output + num_audio_written); + ati->data.assign(resampled_audio_output.begin(), resampled_audio_output.begin() + num_audio_written); audioInputQueue->push(ati); } @@ -116,12 +140,12 @@ void DemodulatorThread::threadMain() { if (num_vis > num_audio_written) { num_vis = num_audio_written; } - ati_vis->data.assign(resampled_audio_output, resampled_audio_output + num_vis); + ati_vis->data.assign(resampled_audio_output.begin(), resampled_audio_output.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.assign(demod_output.begin(), demod_output.begin() + num_vis); } visOutQueue->push(ati_vis); diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index b80c5da..d0e3b96 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -53,6 +53,7 @@ void SDRPostThread::threadMain() { std::deque buffers; std::deque::iterator buffers_i; + std::vector dataOut; while (!terminated) { SDRThreadIQData *data_in; @@ -61,29 +62,34 @@ void SDRPostThread::threadMain() { // std::lock_guard < std::mutex > lock(data_in->m_mutex); if (data_in && data_in->data.size()) { - SDRThreadIQData *dataOut = new SDRThreadIQData; + if (data_in->data.size() > dataOut.capacity()) { + dataOut.reserve(data_in->data.size()); + } - dataOut->frequency = data_in->frequency; - dataOut->bandwidth = data_in->bandwidth; - dataOut->data.assign(data_in->data.begin(), data_in->data.end()); + dataOut.assign(data_in->data.begin(), data_in->data.end()); - 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.size() / 2; i < iMax; i++) { + x.real = (float) dataOut[i * 2] / 127.0; + x.imag = (float) dataOut[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[i * 2] = (signed char) floor(y.real * 127.0); + dataOut[i * 2 + 1] = (signed char) floor(y.imag * 127.0); } if (iqDataOutQueue != NULL) { - iqDataOutQueue.load()->push(dataOut); + SDRThreadIQData *visDataOut = new SDRThreadIQData; + + visDataOut->frequency = data_in->frequency; + visDataOut->bandwidth = data_in->bandwidth; + visDataOut->data.assign(dataOut.begin(), dataOut.end()); + iqDataOutQueue.load()->push(visDataOut); } if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) { SDRThreadIQData *visualDataOut = new SDRThreadIQData; - visualDataOut->data.assign(dataOut->data.begin(), dataOut->data.begin() + (FFT_SIZE * 2)); + visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + (FFT_SIZE * 2)); iqVisualQueue.load()->push(visualDataOut); } @@ -142,7 +148,7 @@ void SDRPostThread::threadMain() { demodDataOut->frequency = data_in->frequency; demodDataOut->bandwidth = data_in->bandwidth; demodDataOut->setRefCount(activeDemods); - demodDataOut->data.assign(dataOut->data.begin(), dataOut->data.begin() + dataOut->data.size()); + demodDataOut->data.assign(dataOut.begin(), dataOut.begin() + dataOut.size()); std::vector::iterator i; for (i = demodulators.begin(); i != demodulators.end(); i++) { @@ -175,7 +181,6 @@ void SDRPostThread::threadMain() { } } } - delete dataOut; } data_in->decRefCount(); } diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index b52f960..932dfa2 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -181,6 +181,10 @@ void SDRThread::threadMain() { dataOut->frequency = frequency; dataOut->bandwidth = bandwidth; + if (dataOut->data.capacity() < n_read) { + dataOut->data.reserve(n_read); + } + if (dataOut->data.size() != n_read) { dataOut->data.resize(n_read); } From 45b223aed9f74a963b38580e61d0bb4702e8d278 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 26 Dec 2014 16:15:35 -0500 Subject: [PATCH 13/13] eliminate fp/int IQ data conversions --- src/AppFrame.cpp | 2 +- src/CubicSDR.cpp | 4 +-- src/CubicSDR.h | 4 +-- src/demod/DemodDefs.h | 2 +- src/demod/DemodulatorPreThread.cpp | 11 +++---- src/sdr/SDRPostThread.cpp | 50 +++++++++++++++--------------- src/sdr/SDRPostThread.h | 8 ++--- src/visual/SpectrumCanvas.cpp | 6 ++-- src/visual/SpectrumCanvas.h | 2 +- src/visual/WaterfallCanvas.cpp | 6 ++-- src/visual/WaterfallCanvas.h | 2 +- 11 files changed, 47 insertions(+), 50 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 50a088c..beb251f 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -96,7 +96,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) { // std::this_thread::yield(); //#endif if (!wxGetApp().getIQVisualQueue()->empty()) { - SDRThreadIQData *iqData; + DemodulatorThreadIQData *iqData; wxGetApp().getIQVisualQueue()->pop(iqData); if (iqData && iqData->data.size()) { diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index fc78863..f2e6e8a 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -30,7 +30,7 @@ bool CubicSDR::OnInit() { sdrPostThread = new SDRPostThread(); iqPostDataQueue = new SDRThreadIQDataQueue; - iqVisualQueue = new SDRThreadIQDataQueue; + iqVisualQueue = new DemodulatorThreadInputQueue; iqVisualQueue->set_max_num_items(1); sdrThread->setIQDataOutQueue(iqPostDataQueue); @@ -115,7 +115,7 @@ DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { return audioVisualQueue; } -SDRThreadIQDataQueue* CubicSDR::getIQVisualQueue() { +DemodulatorThreadInputQueue* CubicSDR::getIQVisualQueue() { return iqVisualQueue; } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 4790aef..b84e23e 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -33,7 +33,7 @@ public: int getFrequency(); DemodulatorThreadOutputQueue* getAudioVisualQueue(); - SDRThreadIQDataQueue* getIQVisualQueue(); + DemodulatorThreadInputQueue* getIQVisualQueue(); DemodulatorMgr &getDemodMgr(); void bindDemodulator(DemodulatorInstance *demod); @@ -50,8 +50,8 @@ private: SDRPostThread *sdrPostThread; SDRThreadCommandQueue* threadCmdQueueSDR; - SDRThreadIQDataQueue* iqVisualQueue; SDRThreadIQDataQueue* iqPostDataQueue; + DemodulatorThreadInputQueue* iqVisualQueue; DemodulatorThreadOutputQueue* audioVisualQueue; std::thread *t_SDR; diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 29d8d05..c8ddf22 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -55,7 +55,7 @@ class DemodulatorThreadIQData: public ReferenceCounter { public: unsigned int frequency; unsigned int bandwidth; - std::vector data; + std::vector data; DemodulatorThreadIQData() : frequency(0), bandwidth(0) { diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index f0e26d4..065141f 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -166,9 +166,9 @@ void DemodulatorPreThread::threadMain() { } // std::lock_guard < std::mutex > lock(inp->m_mutex); - std::vector *data = &inp->data; + std::vector *data = &inp->data; if (data->size()) { - int bufSize = data->size() / 2; + int bufSize = data->size(); if (in_buf_data.size() != bufSize) { if (in_buf_data.capacity() < bufSize) { @@ -179,15 +179,12 @@ void DemodulatorPreThread::threadMain() { out_buf_data.resize(bufSize); } + in_buf_data.assign(inp->data.begin(),inp->data.end()); + liquid_float_complex *in_buf = &in_buf_data[0]; liquid_float_complex *out_buf = &out_buf_data[0]; liquid_float_complex *temp_buf = NULL; - for (int i = 0; i < bufSize; i++) { - in_buf[i].real = (float) (*data)[i * 2] / 127.0f; - in_buf[i].imag = (float) (*data)[i * 2 + 1] / 127.0f; - } - if (shift_freq != 0) { if (shift_freq < 0) { nco_crcf_mix_block_up(nco_shift, in_buf, out_buf, bufSize); diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index d0e3b96..bb93b6d 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -27,10 +27,10 @@ void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) { void SDRPostThread::setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) { iqDataInQueue = iqDataQueue; } -void SDRPostThread::setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue) { +void SDRPostThread::setIQDataOutQueue(DemodulatorThreadInputQueue* iqDataQueue) { iqDataOutQueue = iqDataQueue; } -void SDRPostThread::setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue) { +void SDRPostThread::setIQVisualQueue(DemodulatorThreadInputQueue *iqVisQueue) { iqVisualQueue = iqVisQueue; } @@ -47,13 +47,12 @@ void SDRPostThread::threadMain() { dcFilter = iirfilt_crcf_create_dc_blocker(0.0005); - liquid_float_complex x, y; - std::cout << "SDR post-processing thread started.." << std::endl; std::deque buffers; std::deque::iterator buffers_i; - std::vector dataOut; + std::vector fpData; + std::vector dataOut; while (!terminated) { SDRThreadIQData *data_in; @@ -62,34 +61,35 @@ void SDRPostThread::threadMain() { // std::lock_guard < std::mutex > lock(data_in->m_mutex); if (data_in && data_in->data.size()) { - if (data_in->data.size() > dataOut.capacity()) { - dataOut.reserve(data_in->data.size()); + int dataSize = data_in->data.size()/2; + if (dataSize > fpData.capacity()) { + fpData.reserve(dataSize); + dataOut.reserve(dataSize); + } + if (dataSize != fpData.size()) { + fpData.resize(dataSize); + dataOut.resize(dataSize); } - dataOut.assign(data_in->data.begin(), data_in->data.end()); - - for (int i = 0, iMax = dataOut.size() / 2; i < iMax; i++) { - x.real = (float) dataOut[i * 2] / 127.0; - x.imag = (float) dataOut[i * 2 + 1] / 127.0; - - iirfilt_crcf_execute(dcFilter, x, &y); - - dataOut[i * 2] = (signed char) floor(y.real * 127.0); - dataOut[i * 2 + 1] = (signed char) floor(y.imag * 127.0); + for (int i = 0, iMax = dataSize; i < iMax; i++) { + fpData[i].real = (float) data_in->data[i * 2] / 127.0; + fpData[i].imag = (float) data_in->data[i * 2 + 1] / 127.0; } + iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]); + if (iqDataOutQueue != NULL) { - SDRThreadIQData *visDataOut = new SDRThreadIQData; + DemodulatorThreadIQData *pipeDataOut = new DemodulatorThreadIQData; - visDataOut->frequency = data_in->frequency; - visDataOut->bandwidth = data_in->bandwidth; - visDataOut->data.assign(dataOut.begin(), dataOut.end()); - iqDataOutQueue.load()->push(visDataOut); + pipeDataOut->frequency = data_in->frequency; + pipeDataOut->bandwidth = data_in->bandwidth; + pipeDataOut->data.assign(dataOut.begin(), dataOut.end()); + iqDataOutQueue.load()->push(pipeDataOut); } if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) { - SDRThreadIQData *visualDataOut = new SDRThreadIQData; - visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + (FFT_SIZE * 2)); + DemodulatorThreadIQData *visualDataOut = new DemodulatorThreadIQData; + visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + FFT_SIZE); iqVisualQueue.load()->push(visualDataOut); } @@ -148,7 +148,7 @@ void SDRPostThread::threadMain() { demodDataOut->frequency = data_in->frequency; demodDataOut->bandwidth = data_in->bandwidth; demodDataOut->setRefCount(activeDemods); - demodDataOut->data.assign(dataOut.begin(), dataOut.begin() + dataOut.size()); + demodDataOut->data.assign(dataOut.begin(), dataOut.end()); std::vector::iterator i; for (i = demodulators.begin(); i != demodulators.end(); i++) { diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 6846aa1..e70f082 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -12,8 +12,8 @@ public: void removeDemodulator(DemodulatorInstance *demod); void setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue); - void setIQDataOutQueue(SDRThreadIQDataQueue* iqDataQueue); - void setIQVisualQueue(SDRThreadIQDataQueue* iqVisQueue); + void setIQDataOutQueue(DemodulatorThreadInputQueue* iqDataQueue); + void setIQVisualQueue(DemodulatorThreadInputQueue* iqVisQueue); void threadMain(); void terminate(); @@ -21,9 +21,9 @@ public: protected: uint32_t sample_rate; - std::atomic iqDataOutQueue; std::atomic iqDataInQueue; - std::atomic iqVisualQueue; + std::atomic iqDataOutQueue; + std::atomic iqVisualQueue; std::vector demodulators; std::vector demodulators_add; diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 1ac98ef..e9b9c27 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -73,7 +73,7 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { SwapBuffers(); } -void SpectrumCanvas::setData(std::vector *data) { +void SpectrumCanvas::setData(std::vector *data) { if (data && data->size()) { if (spectrum_points.size() < FFT_SIZE * 2) { @@ -81,8 +81,8 @@ void SpectrumCanvas::setData(std::vector *data) { } 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; + in[i][0] = (*data)[i].real; + in[i][1] = (*data)[i].imag; } fftw_execute(plan); diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index 5f96fd5..d02f4fe 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -17,7 +17,7 @@ public: SpectrumCanvas(wxWindow *parent, int *attribList = NULL); ~SpectrumCanvas(); - void setData(std::vector *data); + void setData(std::vector *data); private: void OnPaint(wxPaintEvent& event); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 1b82be2..2d07282 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -206,7 +206,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { } } -void WaterfallCanvas::setData(std::vector *data) { +void WaterfallCanvas::setData(std::vector *data) { if (data && data->size()) { if (spectrum_points.size() < FFT_SIZE * 2) { @@ -214,8 +214,8 @@ void WaterfallCanvas::setData(std::vector *data) { } 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; + in[i][0] = (*data)[i].real; + in[i][1] = (*data)[i].imag; } fftw_execute(plan); diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 2600682..e320a73 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -21,7 +21,7 @@ public: WaterfallCanvas(wxWindow *parent, int *attribList = NULL); ~WaterfallCanvas(); - void setData(std::vector *data); + void setData(std::vector *data); int GetFrequencyAt(float x); private: