SDR thread reusable buffers implemented

This commit is contained in:
Charles J. Cliffe 2014-12-24 00:11:41 -05:00
parent b7375ce09f
commit 8c852ed491
6 changed files with 66 additions and 31 deletions

View File

@ -11,3 +11,25 @@
#define DEFAULT_FREQ 98900000 #define DEFAULT_FREQ 98900000
#define AUDIO_FREQUENCY 44100 #define AUDIO_FREQUENCY 44100
#include <mutex>
#include <atomic>
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<int> refCount;
};

View File

@ -18,11 +18,12 @@
#include "RtAudio.h" #include "RtAudio.h"
#include "DemodDefs.h" #include "DemodDefs.h"
class AudioThreadInput { class AudioThreadInput: public ReferenceCounter {
public: public:
int frequency; int frequency;
int sampleRate; int sampleRate;
int channels; int channels;
std::vector<float> data;
AudioThreadInput(): frequency(0), sampleRate(0), channels(0) { AudioThreadInput(): frequency(0), sampleRate(0), channels(0) {
@ -31,8 +32,6 @@ public:
~AudioThreadInput() { ~AudioThreadInput() {
} }
std::vector<float> data;
}; };
class AudioThreadCommand { class AudioThreadCommand {

View File

@ -56,39 +56,23 @@ public:
DemodulatorThreadControlCommandEnum cmd; DemodulatorThreadControlCommandEnum cmd;
}; };
class DemodulatorThreadIQData { class DemodulatorThreadIQData : public ReferenceCounter {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int bandwidth; unsigned int bandwidth;
std::vector<signed char> data; std::vector<signed char> data;
mutable std::mutex m_mutex;
DemodulatorThreadIQData() : 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() { ~DemodulatorThreadIQData() {
} }
private:
std::atomic<int> refCount;
}; };
class DemodulatorThreadPostIQData { class DemodulatorThreadPostIQData : public ReferenceCounter {
public: public:
std::vector<liquid_float_complex> data; std::vector<liquid_float_complex> data;
float audio_resample_ratio; float audio_resample_ratio;
@ -106,7 +90,7 @@ public:
}; };
class DemodulatorThreadAudioData { class DemodulatorThreadAudioData : public ReferenceCounter {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int sampleRate; unsigned int sampleRate;

View File

@ -58,6 +58,7 @@ void SDRPostThread::threadMain() {
SDRThreadIQData *data_in; SDRThreadIQData *data_in;
iqDataInQueue.load()->pop(data_in); iqDataInQueue.load()->pop(data_in);
// std::lock_guard < std::mutex > lock(data_in->m_mutex);
if (data_in && data_in->data.size()) { if (data_in && data_in->data.size()) {
SDRThreadIQData *dataOut = new SDRThreadIQData; SDRThreadIQData *dataOut = new SDRThreadIQData;
@ -176,9 +177,7 @@ void SDRPostThread::threadMain() {
} }
delete dataOut; delete dataOut;
} }
if (data_in) { data_in->decRefCount();
delete data_in;
}
} }
while (!buffers.empty()) { while (!buffers.empty()) {

View File

@ -91,7 +91,7 @@ int SDRThread::enumerate_rtl() {
void SDRThread::threadMain() { void SDRThread::threadMain() {
#ifdef __APPLE__ #ifdef __APPLE__
pthread_t tID = pthread_self(); // ID of this thread 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 sched_param prio = { priority }; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_FIFO, &prio); pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif #endif
@ -128,6 +128,10 @@ void SDRThread::threadMain() {
double seconds = 0.0; double seconds = 0.0;
std::cout << "SDR thread started.." << std::endl; std::cout << "SDR thread started.." << std::endl;
std::deque<SDRThreadIQData *> buffers;
std::deque<SDRThreadIQData *>::iterator buffers_i;
while (!terminated) { while (!terminated) {
SDRThreadCommandQueue *cmdQueue = m_pQueue.load(); SDRThreadCommandQueue *cmdQueue = m_pQueue.load();
@ -145,7 +149,7 @@ void SDRThread::threadMain() {
freq_changed = true; freq_changed = true;
new_freq = command.int_value; new_freq = command.int_value;
break; break;
default: default:
break; break;
} }
} }
@ -158,12 +162,31 @@ void SDRThread::threadMain() {
rtlsdr_read_sync(dev, buf, BUF_SIZE, &n_read); 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->frequency = frequency;
dataOut->bandwidth = bandwidth; dataOut->bandwidth = bandwidth;
if (dataOut->data.size() != n_read) {
dataOut->data.resize(n_read);
}
for (int i = 0; i < n_read; i++) { 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; double time_slice = (double) n_read / (double) sample_rate;
@ -173,6 +196,14 @@ void SDRThread::threadMain() {
iqDataOutQueue.load()->push(dataOut); 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; std::cout << "SDR thread done." << std::endl;
} }

View File

@ -34,7 +34,7 @@ public:
int int_value; int int_value;
}; };
class SDRThreadIQData { class SDRThreadIQData : public ReferenceCounter {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int bandwidth; unsigned int bandwidth;