CubicSDR/src/sdr/SDRPostThread.cpp

222 lines
7.9 KiB
C++
Raw Normal View History

#include "SDRPostThread.h"
#include "CubicSDRDefs.h"
#include "CubicSDR.h"
#include <vector>
#include <deque>
SDRPostThread::SDRPostThread() :
2015-01-11 17:08:16 -05:00
iqDataOutQueue(NULL), iqDataInQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL), num_vis_samples(2048) {
}
SDRPostThread::~SDRPostThread() {
2014-12-11 19:07:21 -05:00
}
void SDRPostThread::bindDemodulator(DemodulatorInstance *demod) {
demodulators_add.push_back(demod);
2014-12-11 19:07:21 -05:00
}
void SDRPostThread::removeDemodulator(DemodulatorInstance *demod) {
if (!demod) {
return;
}
demodulators_remove.push_back(demod);
2014-12-11 19:07:21 -05:00
}
void SDRPostThread::setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) {
iqDataInQueue = iqDataQueue;
}
2014-12-26 16:15:35 -05:00
void SDRPostThread::setIQDataOutQueue(DemodulatorThreadInputQueue* iqDataQueue) {
2014-12-11 19:07:21 -05:00
iqDataOutQueue = iqDataQueue;
}
2014-12-26 16:15:35 -05:00
void SDRPostThread::setIQVisualQueue(DemodulatorThreadInputQueue *iqVisQueue) {
2014-12-11 19:07:21 -05:00
iqVisualQueue = iqVisQueue;
}
void SDRPostThread::setNumVisSamples(int num_vis_samples_in) {
num_vis_samples = num_vis_samples_in;
}
int SDRPostThread::getNumVisSamples() {
return num_vis_samples;
}
void SDRPostThread::threadMain() {
int n_read;
double seconds = 0.0;
#ifdef __APPLE__
pthread_t tID = pthread_self(); // ID of this thread
int priority = sched_get_priority_max( SCHED_FIFO) - 1;
2014-12-24 01:28:33 -05:00
sched_param prio = {priority}; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif
dcFilter = iirfilt_crcf_create_dc_blocker(0.0005);
DemodulatorThreadIQData *visualDataOut = new DemodulatorThreadIQData;
std::cout << "SDR post-processing thread started.." << std::endl;
std::deque<DemodulatorThreadIQData *> buffers;
std::deque<DemodulatorThreadIQData *>::iterator buffers_i;
2014-12-26 16:15:35 -05:00
std::vector<liquid_float_complex> fpData;
std::vector<liquid_float_complex> dataOut;
while (!terminated) {
2014-12-23 01:59:03 -05:00
SDRThreadIQData *data_in;
iqDataInQueue.load()->pop(data_in);
// std::lock_guard < std::mutex > lock(data_in->m_mutex);
2014-12-23 01:59:03 -05:00
if (data_in && data_in->data.size()) {
2014-12-26 16:15:35 -05:00
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);
}
2014-12-26 16:15:35 -05:00
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;
}
2014-12-26 16:15:35 -05:00
iirfilt_crcf_execute_block(dcFilter, &fpData[0], dataSize, &dataOut[0]);
if (iqDataOutQueue != NULL) {
2014-12-26 16:15:35 -05:00
DemodulatorThreadIQData *pipeDataOut = new DemodulatorThreadIQData;
2014-12-26 16:15:35 -05:00
pipeDataOut->frequency = data_in->frequency;
2015-01-11 17:08:16 -05:00
pipeDataOut->sampleRate = data_in->sampleRate;
2014-12-26 16:15:35 -05:00
pipeDataOut->data.assign(dataOut.begin(), dataOut.end());
iqDataOutQueue.load()->push(pipeDataOut);
}
if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) {
if (visualDataOut->data.size() < num_vis_samples) {
if (visualDataOut->data.capacity() < num_vis_samples) {
visualDataOut->data.reserve(num_vis_samples);
}
visualDataOut->data.resize(num_vis_samples);
}
visualDataOut->frequency = data_in->frequency;
2015-01-11 17:08:16 -05:00
visualDataOut->sampleRate = data_in->sampleRate;
visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples);
iqVisualQueue.load()->push(visualDataOut);
}
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<DemodulatorInstance *>::iterator i = std::find(demodulators.begin(), demodulators.end(), demod);
if (i != demodulators.end()) {
demodulators.erase(i);
}
}
}
int activeDemods = 0;
bool pushedData = false;
if (demodulators.size()) {
std::vector<DemodulatorInstance *>::iterator i;
for (i = demodulators.begin(); i != demodulators.end(); i++) {
DemodulatorInstance *demod = *i;
2015-01-10 12:27:03 -05:00
if (demod->getFrequency() != data_in->frequency
2015-01-11 17:08:16 -05:00
&& abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
continue;
}
activeDemods++;
}
if (demodulators.size()) {
2014-12-24 01:28:33 -05:00
DemodulatorThreadIQData *demodDataOut = NULL;
2014-12-24 01:28:33 -05:00
for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) {
if ((*buffers_i)->getRefCount() <= 0) {
demodDataOut = (*buffers_i);
break;
}
}
2014-12-24 01:28:33 -05:00
if (demodDataOut == NULL) {
demodDataOut = new DemodulatorThreadIQData;
buffers.push_back(demodDataOut);
}
2014-12-24 01:28:33 -05:00
// std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
2014-12-23 01:59:03 -05:00
demodDataOut->frequency = data_in->frequency;
2015-01-11 17:08:16 -05:00
demodDataOut->sampleRate = data_in->sampleRate;
2014-12-22 23:27:52 -05:00
demodDataOut->setRefCount(activeDemods);
2014-12-26 16:15:35 -05:00
demodDataOut->data.assign(dataOut.begin(), dataOut.end());
std::vector<DemodulatorInstance *>::iterator i;
for (i = demodulators.begin(); i != demodulators.end(); i++) {
DemodulatorInstance *demod = *i;
DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod;
2015-01-10 12:27:03 -05:00
if (demod->getFrequency() != data_in->frequency
2015-01-11 17:08:16 -05:00
&& abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) {
if (demod->isActive()) {
demod->setActive(false);
2014-12-22 23:27:52 -05:00
DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData;
2014-12-23 01:59:03 -05:00
dummyDataOut->frequency = data_in->frequency;
2015-01-11 17:08:16 -05:00
dummyDataOut->sampleRate = data_in->sampleRate;
demodQueue->push(dummyDataOut);
}
} else if (!demod->isActive()) {
demod->setActive(true);
}
if (!demod->isActive()) {
continue;
}
demodQueue->push(demodDataOut);
pushedData = true;
}
2014-12-22 23:27:52 -05:00
if (!pushedData) {
demodDataOut->setRefCount(0);
2014-12-22 23:27:52 -05:00
}
}
}
2014-12-23 01:59:03 -05:00
}
data_in->decRefCount();
}
while (!buffers.empty()) {
DemodulatorThreadIQData *demodDataDel = buffers.front();
buffers.pop_front();
2014-12-24 01:28:33 -05:00
// std::lock_guard < std::mutex > lock(demodDataDel->m_mutex);
// delete demodDataDel;
}
delete visualDataOut;
std::cout << "SDR post-processing thread done." << std::endl;
}
void SDRPostThread::terminate() {
terminated = true;
2014-12-23 01:59:03 -05:00
SDRThreadIQData *dummy = new SDRThreadIQData;
iqDataInQueue.load()->push(dummy);
}