CubicSDR/src/demod/DemodulatorWorkerThread.cpp

117 lines
4.5 KiB
C++
Raw Normal View History

// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
2014-11-30 23:33:55 -05:00
#include "DemodulatorWorkerThread.h"
#include "CubicSDRDefs.h"
#include "CubicSDR.h"
2014-11-30 23:33:55 -05:00
#include <vector>
DemodulatorWorkerThread::DemodulatorWorkerThread() : IOThread(),
commandQueue(NULL), resultQueue(NULL), cModem(nullptr), cModemKit(nullptr) {
2014-11-30 23:33:55 -05:00
}
DemodulatorWorkerThread::~DemodulatorWorkerThread() {
}
2015-07-29 20:57:02 -04:00
void DemodulatorWorkerThread::run() {
2014-11-30 23:33:55 -05:00
// std::cout << "Demodulator worker thread started.." << std::endl;
commandQueue = static_cast<DemodulatorThreadWorkerCommandQueue *>(getInputQueue("WorkerCommandQueue"));
resultQueue = static_cast<DemodulatorThreadWorkerResultQueue *>(getOutputQueue("WorkerResultQueue"));
while (!stopping) {
2014-11-30 23:33:55 -05:00
bool filterChanged = false;
bool makeDemod = false;
2015-11-20 21:41:57 -05:00
DemodulatorWorkerThreadCommand filterCommand, demodCommand;
2014-11-30 23:33:55 -05:00
DemodulatorWorkerThreadCommand command;
bool done = false;
//Beware of the subtility here,
//we are waiting for the first command to show up (blocking!)
//then consuming the commands until done.
2014-11-30 23:33:55 -05:00
while (!done) {
commandQueue->pop(command);
2014-11-30 23:33:55 -05:00
switch (command.cmd) {
case DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS:
filterChanged = true;
filterCommand = command;
break;
case DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_MAKE_DEMOD:
makeDemod = true;
demodCommand = command;
break;
default:
break;
2014-11-30 23:33:55 -05:00
}
done = commandQueue->empty();
}
if ((makeDemod || filterChanged) && !stopping) {
DemodulatorWorkerThreadResult result(DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS);
if (filterCommand.sampleRate) {
result.sampleRate = filterCommand.sampleRate;
2015-01-23 02:09:37 -05:00
}
if (makeDemod) {
2015-11-20 21:41:57 -05:00
cModem = Modem::makeModem(demodCommand.demodType);
cModemName = cModem->getName();
cModemType = cModem->getType();
if (demodCommand.settings.size()) {
cModem->writeSettings(demodCommand.settings);
}
result.sampleRate = demodCommand.sampleRate;
wxGetApp().getAppFrame()->notifyUpdateModemProperties();
}
result.modem = cModem;
2015-11-20 21:41:57 -05:00
if (makeDemod && demodCommand.bandwidth && demodCommand.audioSampleRate) {
if (cModem != nullptr) {
result.bandwidth = cModem->checkSampleRate(demodCommand.bandwidth, demodCommand.audioSampleRate);
cModemKit = cModem->buildKit(result.bandwidth, demodCommand.audioSampleRate);
2015-11-20 21:41:57 -05:00
} else {
cModemKit = nullptr;
}
2015-11-21 02:13:33 -05:00
} else if (filterChanged && filterCommand.bandwidth && filterCommand.audioSampleRate) {
if (cModem != nullptr) {
result.bandwidth = cModem->checkSampleRate(filterCommand.bandwidth, filterCommand.audioSampleRate);
cModemKit = cModem->buildKit(result.bandwidth, filterCommand.audioSampleRate);
2015-11-21 02:13:33 -05:00
} else {
cModemKit = nullptr;
}
2015-11-20 21:41:57 -05:00
} else if (makeDemod) {
cModemKit = nullptr;
2015-01-23 02:09:37 -05:00
}
if (cModem != nullptr) {
cModem->clearRebuildKit();
}
float As = 60.0f; // stop-band attenuation [dB]
2016-03-30 19:34:36 -04:00
if (cModem && result.sampleRate && result.bandwidth) {
result.bandwidth = cModem->checkSampleRate(result.bandwidth, makeDemod?demodCommand.audioSampleRate:filterCommand.audioSampleRate);
result.iqResampleRatio = (double) (result.bandwidth) / (double) result.sampleRate;
result.iqResampler = msresamp_crcf_create(result.iqResampleRatio, As);
2015-01-23 02:09:37 -05:00
}
result.modemKit = cModemKit;
result.modemType = cModemType;
result.modemName = cModemName;
2014-11-30 23:33:55 -05:00
resultQueue->push(result);
}
}
// std::cout << "Demodulator worker thread done." << std::endl;
2014-11-30 23:33:55 -05:00
}
void DemodulatorWorkerThread::terminate() {
IOThread::terminate();
2014-11-30 23:33:55 -05:00
DemodulatorWorkerThreadCommand inp; // push dummy to nudge queue
commandQueue->push(inp);
}