Allow modems to limit/control input rate

- Modems can now over-ride user rate input and lock/step as needed
- Separate digital code defs a bit more so it’s not required when
disabled
- Testing FSK based on @andresv ’s example at
https://github.com/jgaeddert/liquid-dsp/issues/9
This commit is contained in:
Charles J. Cliffe
2015-11-22 19:56:25 -05:00
parent 724808d9ff
commit c0eca0b2f3
26 changed files with 242 additions and 105 deletions
+7 -29
View File
@@ -14,7 +14,6 @@ DemodulatorInstance::DemodulatorInstance() :
follow.store(false);
currentAudioSampleRate.store(0);
currentFrequency.store(0);
currentBandwidth.store(0);
currentOutputDevice.store(-1);
currentAudioGain.store(1.0);
@@ -24,7 +23,7 @@ DemodulatorInstance::DemodulatorInstance() :
pipeDemodCommand = new DemodulatorThreadCommandQueue;
pipeDemodNotify = new DemodulatorThreadCommandQueue;
demodulatorPreThread = new DemodulatorPreThread();
demodulatorPreThread = new DemodulatorPreThread(this);
demodulatorPreThread->setInputQueue("IQDataInput",pipeIQInputData);
demodulatorPreThread->setOutputQueue("IQDataOutput",pipeIQDemodData);
demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify);
@@ -254,12 +253,6 @@ int DemodulatorInstance::getOutputDevice() {
return currentOutputDevice;
}
void DemodulatorInstance::checkBandwidth() {
// if ((currentDemodType == DEMOD_TYPE_USB || currentDemodType == DEMOD_TYPE_LSB) && (getBandwidth() % 2)) {
// setBandwidth(getBandwidth()+1);
// }
}
void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) {
currentDemodType = demod_type_in;
@@ -274,7 +267,6 @@ void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) {
demodulatorPreThread->getParams().demodType = currentDemodType;
if (!active) {
checkBandwidth();
demodulatorPreThread->setDemodType(currentDemodType);
} else if (demodulatorThread && threadQueueControl) {
demodulatorPreThread->setDemodType(currentDemodType);
@@ -318,32 +310,18 @@ int DemodulatorInstance::getDemodulatorCons() {
}
void DemodulatorInstance::setBandwidth(int bw) {
if (currentDemodType == "I/Q") {
if (currentAudioSampleRate) {
bw = currentAudioSampleRate;
} else {
bw = AudioThread::deviceSampleRate[getOutputDevice()];
}
}
if (!active && demodulatorPreThread != NULL) {
currentBandwidth = bw;
checkBandwidth();
demodulatorPreThread->getParams().bandwidth = currentBandwidth;
demodulatorPreThread->getParams().bandwidth = bw;
} else if (demodulatorPreThread && pipeDemodCommand) {
DemodulatorThreadCommand command;
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH;
currentBandwidth = bw;
checkBandwidth();
command.llong_value = currentBandwidth;
command.llong_value = bw;
pipeDemodCommand->push(command);
}
}
int DemodulatorInstance::getBandwidth() {
if (!currentBandwidth) {
currentBandwidth = demodulatorPreThread->getParams().bandwidth;
}
return currentBandwidth;
return demodulatorPreThread->getParams().bandwidth;
}
void DemodulatorInstance::setFrequency(long long freq) {
@@ -387,9 +365,9 @@ void DemodulatorInstance::setAudioSampleRate(int sampleRate) {
}
int DemodulatorInstance::getAudioSampleRate() {
if (!currentAudioSampleRate) {
currentAudioSampleRate = audioThread->getSampleRate();
}
currentAudioSampleRate = audioThread->getSampleRate();
demodulatorPreThread->getParams().audioSampleRate = currentAudioSampleRate;
return currentAudioSampleRate;
}
-3
View File
@@ -97,8 +97,6 @@ protected:
private:
void checkBandwidth();
std::atomic<std::string *> label; //
std::atomic_bool terminated; //
std::atomic_bool demodTerminated; //
@@ -109,7 +107,6 @@ private:
std::atomic_bool muted;
std::atomic_llong currentFrequency;
std::atomic_int currentBandwidth;
std::string currentDemodType;
std::atomic_int currentOutputDevice;
std::atomic_int currentAudioSampleRate;
+5 -6
View File
@@ -7,10 +7,12 @@
#include "DemodulatorPreThread.h"
#include "CubicSDR.h"
#include "DemodulatorInstance.h"
DemodulatorPreThread::DemodulatorPreThread() : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL), threadQueueNotify(NULL), commandQueue(NULL)
DemodulatorPreThread::DemodulatorPreThread(DemodulatorInstance *parent) : IOThread(), iqResampler(NULL), iqResampleRatio(1), cModem(nullptr), cModemKit(nullptr), iqInputQueue(NULL), iqOutputQueue(NULL), threadQueueNotify(NULL), commandQueue(NULL)
{
initialized.store(false);
this->parent = parent;
freqShifter = nco_crcf_create(LIQUID_VCO);
shiftFrequency = 0;
@@ -82,11 +84,7 @@ void DemodulatorPreThread::run() {
if (command.llong_value < 1500) {
command.llong_value = 1500;
}
if (command.llong_value > params.sampleRate) {
tempParams.bandwidth = params.sampleRate;
} else {
tempParams.bandwidth = command.llong_value;
}
tempParams.bandwidth = command.llong_value;
bandwidthChanged = true;
break;
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_FREQUENCY:
@@ -257,6 +255,7 @@ void DemodulatorPreThread::setParams(DemodulatorThreadParameters &params_in) {
void DemodulatorPreThread::setDemodType(std::string demodType) {
this->newDemodType = demodType;
DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_MAKE_DEMOD);
command.sampleRate = params.sampleRate;
command.demodType = demodType;
command.bandwidth = params.bandwidth;
command.audioSampleRate = params.audioSampleRate;
+4 -1
View File
@@ -7,10 +7,12 @@
#include "DemodDefs.h"
#include "DemodulatorWorkerThread.h"
class DemodulatorInstance;
class DemodulatorPreThread : public IOThread {
public:
DemodulatorPreThread();
DemodulatorPreThread(DemodulatorInstance *parent);
~DemodulatorPreThread();
void run();
@@ -28,6 +30,7 @@ public:
ModemKit *getModemKit();
protected:
DemodulatorInstance *parent;
msresamp_crcf iqResampler;
double iqResampleRatio;
std::vector<liquid_float_complex> resampledData;
+29 -29
View File
@@ -26,62 +26,62 @@ void DemodulatorWorkerThread::run() {
while (!done) {
commandQueue->pop(command);
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;
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;
}
done = commandQueue->empty();
}
if ((makeDemod || filterChanged) && !terminated) {
DemodulatorWorkerThreadResult result(DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS);
float As = 60.0f; // stop-band attenuation [dB]
if (filterCommand.sampleRate && filterCommand.bandwidth) {
result.iqResampleRatio = (double) (filterCommand.bandwidth) / (double) filterCommand.sampleRate;
result.iqResampler = msresamp_crcf_create(result.iqResampleRatio, As);
if (filterCommand.sampleRate) {
result.sampleRate = filterCommand.sampleRate;
}
if (makeDemod) {
cModem = Modem::makeModem(demodCommand.demodType);
cModemType = demodCommand.demodType;
result.sampleRate = demodCommand.sampleRate;
}
result.modem = cModem;
if (makeDemod && demodCommand.bandwidth && demodCommand.audioSampleRate) {
if (cModem != nullptr) {
cModemKit = cModem->buildKit(demodCommand.bandwidth, demodCommand.audioSampleRate);
result.bandwidth = cModem->checkSampleRate(demodCommand.bandwidth, demodCommand.audioSampleRate);
cModemKit = cModem->buildKit(result.bandwidth, demodCommand.audioSampleRate);
} else {
cModemKit = nullptr;
}
} else if (filterChanged && filterCommand.bandwidth && filterCommand.audioSampleRate) {
if (cModem != nullptr) {
cModemKit = cModem->buildKit(filterCommand.bandwidth, filterCommand.audioSampleRate);
result.bandwidth = cModem->checkSampleRate(filterCommand.bandwidth, filterCommand.audioSampleRate);
cModemKit = cModem->buildKit(result.bandwidth, filterCommand.audioSampleRate);
} else {
cModemKit = nullptr;
}
} else if (makeDemod) {
cModemKit = nullptr;
}
float As = 60.0f; // stop-band attenuation [dB]
if (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);
}
result.modemKit = cModemKit;
if (filterCommand.bandwidth) {
result.bandwidth = filterCommand.bandwidth;
}
if (filterCommand.sampleRate) {
result.sampleRate = filterCommand.sampleRate;
}
result.modemType = cModemType;
resultQueue->push(result);