mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-29 15:18:38 -05:00
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:
parent
724808d9ff
commit
c0eca0b2f3
@ -237,16 +237,6 @@ SET (cubicsdr_sources
|
||||
src/modules/modem/Modem.cpp
|
||||
src/modules/modem/ModemAnalog.cpp
|
||||
src/modules/modem/ModemDigital.cpp
|
||||
src/modules/modem/digital/ModemASK.cpp
|
||||
src/modules/modem/digital/ModemAPSK.cpp
|
||||
src/modules/modem/digital/ModemBPSK.cpp
|
||||
src/modules/modem/digital/ModemDPSK.cpp
|
||||
src/modules/modem/digital/ModemPSK.cpp
|
||||
src/modules/modem/digital/ModemOOK.cpp
|
||||
src/modules/modem/digital/ModemST.cpp
|
||||
src/modules/modem/digital/ModemSQAM.cpp
|
||||
src/modules/modem/digital/ModemQAM.cpp
|
||||
src/modules/modem/digital/ModemQPSK.cpp
|
||||
src/modules/modem/analog/ModemAM.cpp
|
||||
src/modules/modem/analog/ModemDSB.cpp
|
||||
src/modules/modem/analog/ModemFM.cpp
|
||||
@ -296,6 +286,23 @@ SET (cubicsdr_sources
|
||||
external/cubicvr2/math/cubic_math.cpp
|
||||
)
|
||||
|
||||
IF(ENABLE_DIGITAL_LAB)
|
||||
SET (cubicsdr_sources
|
||||
${cubicsdr_sources}
|
||||
src/modules/modem/digital/ModemASK.cpp
|
||||
src/modules/modem/digital/ModemAPSK.cpp
|
||||
src/modules/modem/digital/ModemBPSK.cpp
|
||||
src/modules/modem/digital/ModemDPSK.cpp
|
||||
src/modules/modem/digital/ModemFSK.cpp
|
||||
src/modules/modem/digital/ModemPSK.cpp
|
||||
src/modules/modem/digital/ModemOOK.cpp
|
||||
src/modules/modem/digital/ModemST.cpp
|
||||
src/modules/modem/digital/ModemSQAM.cpp
|
||||
src/modules/modem/digital/ModemQAM.cpp
|
||||
src/modules/modem/digital/ModemQPSK.cpp
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET (cubicsdr_headers
|
||||
src/CubicSDRDefs.h
|
||||
src/CubicSDR.h
|
||||
@ -316,16 +323,6 @@ SET (cubicsdr_headers
|
||||
src/modules/modem/Modem.h
|
||||
src/modules/modem/ModemAnalog.h
|
||||
src/modules/modem/ModemDigital.h
|
||||
src/modules/modem/digital/ModemASK.h
|
||||
src/modules/modem/digital/ModemAPSK.h
|
||||
src/modules/modem/digital/ModemBPSK.h
|
||||
src/modules/modem/digital/ModemDPSK.h
|
||||
src/modules/modem/digital/ModemPSK.h
|
||||
src/modules/modem/digital/ModemOOK.h
|
||||
src/modules/modem/digital/ModemST.h
|
||||
src/modules/modem/digital/ModemSQAM.h
|
||||
src/modules/modem/digital/ModemQAM.h
|
||||
src/modules/modem/digital/ModemQPSK.h
|
||||
src/modules/modem/analog/ModemAM.h
|
||||
src/modules/modem/analog/ModemDSB.h
|
||||
src/modules/modem/analog/ModemFM.h
|
||||
@ -391,6 +388,23 @@ SET (cubicsdr_headers
|
||||
external/cubicvr2/math/vec4.h
|
||||
)
|
||||
|
||||
IF(ENABLE_DIGITAL_LAB)
|
||||
SET(cubicsdr_headers
|
||||
${cubicsdr_headers}
|
||||
src/modules/modem/digital/ModemASK.h
|
||||
src/modules/modem/digital/ModemAPSK.h
|
||||
src/modules/modem/digital/ModemBPSK.h
|
||||
src/modules/modem/digital/ModemDPSK.h
|
||||
src/modules/modem/digital/ModemFSK.h
|
||||
src/modules/modem/digital/ModemPSK.h
|
||||
src/modules/modem/digital/ModemOOK.h
|
||||
src/modules/modem/digital/ModemST.h
|
||||
src/modules/modem/digital/ModemSQAM.h
|
||||
src/modules/modem/digital/ModemQAM.h
|
||||
src/modules/modem/digital/ModemQPSK.h
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET (CUBICSDR_RESOURCES
|
||||
${PROJECT_SOURCE_DIR}/font/vera_sans_mono12.fnt
|
||||
${PROJECT_SOURCE_DIR}/font/vera_sans_mono16.fnt
|
||||
@ -414,7 +428,9 @@ SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}")
|
||||
SOURCE_GROUP("Demodulator" REGULAR_EXPRESSION "src/demod/${REG_EXT}")
|
||||
SOURCE_GROUP("Modem" REGULAR_EXPRESSION "src/modules/modem/${REG_EXT}")
|
||||
SOURCE_GROUP("Modem-Analog" REGULAR_EXPRESSION "src/modules/modem/analog/${REG_EXT}")
|
||||
IF(ENABLE_DIGITAL_LAB)
|
||||
SOURCE_GROUP("Modem-Digital" REGULAR_EXPRESSION "src/modules/modem/digital/${REG_EXT}")
|
||||
ENDIF()
|
||||
SOURCE_GROUP("Audio" REGULAR_EXPRESSION "src/audio/${REG_EXT}")
|
||||
SOURCE_GROUP("Utility" REGULAR_EXPRESSION "src/util/${REG_EXT}")
|
||||
SOURCE_GROUP("Visual" REGULAR_EXPRESSION "src/visual/${REG_EXT}")
|
||||
|
@ -85,11 +85,12 @@ AppFrame::AppFrame() :
|
||||
demodModeSelectorAdv->addChoice(2, "BPSK");
|
||||
demodModeSelectorAdv->addChoice(3, "DPSK");
|
||||
demodModeSelectorAdv->addChoice(4, "PSK");
|
||||
demodModeSelectorAdv->addChoice(5, "OOK");
|
||||
demodModeSelectorAdv->addChoice(6, "ST");
|
||||
demodModeSelectorAdv->addChoice(7, "SQAM");
|
||||
demodModeSelectorAdv->addChoice(8, "QAM");
|
||||
demodModeSelectorAdv->addChoice(9, "QPSK");
|
||||
demodModeSelectorAdv->addChoice(5, "FSK");
|
||||
demodModeSelectorAdv->addChoice(6, "OOK");
|
||||
demodModeSelectorAdv->addChoice(7, "ST");
|
||||
demodModeSelectorAdv->addChoice(8, "SQAM");
|
||||
demodModeSelectorAdv->addChoice(9, "QAM");
|
||||
demodModeSelectorAdv->addChoice(10, "QPSK");
|
||||
demodModeSelectorAdv->setHelpTip("Choose advanced modulation types.");
|
||||
demodTray->Add(demodModeSelectorAdv, 3, wxEXPAND | wxALL, 0);
|
||||
|
||||
|
@ -172,16 +172,19 @@ bool CubicSDR::OnInit() {
|
||||
Modem::addModemFactory(new ModemDSB);
|
||||
Modem::addModemFactory(new ModemIQ);
|
||||
|
||||
#ifdef ENABLE_DIGITAL_LAB
|
||||
Modem::addModemFactory(new ModemAPSK);
|
||||
Modem::addModemFactory(new ModemASK);
|
||||
Modem::addModemFactory(new ModemBPSK);
|
||||
Modem::addModemFactory(new ModemDPSK);
|
||||
Modem::addModemFactory(new ModemFSK);
|
||||
Modem::addModemFactory(new ModemOOK);
|
||||
Modem::addModemFactory(new ModemPSK);
|
||||
Modem::addModemFactory(new ModemQAM);
|
||||
Modem::addModemFactory(new ModemQPSK);
|
||||
Modem::addModemFactory(new ModemSQAM);
|
||||
Modem::addModemFactory(new ModemST);
|
||||
#endif
|
||||
|
||||
frequency = wxGetApp().getConfig()->getCenterFreq();
|
||||
offset = 0;
|
||||
|
@ -37,16 +37,19 @@
|
||||
#include "ModemDSB.h"
|
||||
#include "ModemIQ.h"
|
||||
|
||||
#ifdef ENABLE_DIGITAL_LAB
|
||||
#include "ModemAPSK.h"
|
||||
#include "ModemASK.h"
|
||||
#include "ModemBPSK.h"
|
||||
#include "ModemDPSK.h"
|
||||
#include "ModemFSK.h"
|
||||
#include "ModemOOK.h"
|
||||
#include "ModemPSK.h"
|
||||
#include "ModemQAM.h"
|
||||
#include "ModemQPSK.h"
|
||||
#include "ModemSQAM.h"
|
||||
#include "ModemST.h"
|
||||
#endif
|
||||
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 ¶ms_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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -44,6 +44,7 @@ public:
|
||||
Modem();
|
||||
virtual ~Modem();
|
||||
|
||||
virtual int checkSampleRate(long long sampleRate, int audioSampleRate) = 0;
|
||||
virtual ModemKit *buildKit(long long sampleRate, int audioSampleRate) = 0;
|
||||
virtual void disposeKit(ModemKit *kit) = 0;
|
||||
virtual void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) = 0;
|
||||
|
@ -8,6 +8,10 @@ std::string ModemAnalog::getType() {
|
||||
return "analog";
|
||||
}
|
||||
|
||||
int ModemAnalog::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
ModemKit *ModemAnalog::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKitAnalog *akit = new ModemKitAnalog;
|
||||
|
||||
|
@ -16,12 +16,13 @@ class ModemAnalog : public Modem {
|
||||
public:
|
||||
ModemAnalog();
|
||||
std::string getType();
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
void initOutputBuffers(ModemKitAnalog *akit, ModemIQData *input);
|
||||
void buildAudioOutput(ModemKitAnalog *akit, AudioThreadInput *audioOut, bool autoGain);
|
||||
std::vector<float> *getDemodOutputData();
|
||||
std::vector<float> *getResampledOutputData();
|
||||
virtual int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
virtual ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
virtual void disposeKit(ModemKit *kit);
|
||||
virtual void initOutputBuffers(ModemKitAnalog *akit, ModemIQData *input);
|
||||
virtual void buildAudioOutput(ModemKitAnalog *akit, AudioThreadInput *audioOut, bool autoGain);
|
||||
virtual std::vector<float> *getDemodOutputData();
|
||||
virtual std::vector<float> *getResampledOutputData();
|
||||
protected:
|
||||
int bufSize;
|
||||
std::vector<float> demodOutputData;
|
||||
|
@ -8,6 +8,10 @@ std::string ModemDigital::getType() {
|
||||
return "digital";
|
||||
}
|
||||
|
||||
int ModemDigital::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
ModemKit *ModemDigital::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKitDigital *dkit = new ModemKitDigital;
|
||||
|
||||
|
@ -13,10 +13,11 @@ class ModemDigital : public Modem {
|
||||
public:
|
||||
ModemDigital();
|
||||
std::string getType();
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
void digitalStart(ModemKitDigital *kit, modem mod, ModemIQData *input);
|
||||
void digitalFinish(ModemKitDigital *kit, modem mod);
|
||||
virtual int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
virtual ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
virtual void disposeKit(ModemKit *kit);
|
||||
virtual void digitalStart(ModemKitDigital *kit, modem mod, ModemIQData *input);
|
||||
virtual void digitalFinish(ModemKitDigital *kit, modem mod);
|
||||
|
||||
virtual void setDemodulatorLock(bool demod_lock_in);
|
||||
virtual int getDemodulatorLock();
|
||||
|
@ -30,6 +30,14 @@ Modem *ModemFMStereo::factory() {
|
||||
return new ModemFMStereo;
|
||||
}
|
||||
|
||||
int ModemFMStereo::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
if (sampleRate < 100000) {
|
||||
return 100000;
|
||||
} else {
|
||||
return sampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKitFMStereo *kit = new ModemKitFMStereo;
|
||||
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
std::string getType();
|
||||
std::string getName();
|
||||
Modem *factory();
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
@ -10,6 +10,8 @@ Modem *ModemIQ::factory() {
|
||||
|
||||
ModemKit *ModemIQ::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKit *kit = new ModemKit;
|
||||
kit->sampleRate = sampleRate;
|
||||
kit->audioSampleRate = audioSampleRate;
|
||||
return kit;
|
||||
}
|
||||
|
||||
@ -25,6 +27,10 @@ void ModemIQ::disposeKit(ModemKit *kit) {
|
||||
delete kit;
|
||||
}
|
||||
|
||||
int ModemIQ::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
return audioSampleRate;
|
||||
}
|
||||
|
||||
void ModemIQ::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
int bufSize = input->data.size();
|
||||
|
||||
|
@ -8,6 +8,7 @@ public:
|
||||
std::string getName();
|
||||
Modem *factory();
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
|
@ -19,6 +19,13 @@ ModemLSB::~ModemLSB() {
|
||||
ampmodem_destroy(demodAM_LSB);
|
||||
}
|
||||
|
||||
int ModemLSB::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
if (sampleRate % 2 == 0) {
|
||||
return sampleRate;
|
||||
}
|
||||
return sampleRate+1;
|
||||
}
|
||||
|
||||
void ModemLSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *akit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
@ -8,6 +8,7 @@ public:
|
||||
~ModemLSB();
|
||||
std::string getName();
|
||||
Modem *factory();
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
@ -19,6 +19,13 @@ ModemUSB::~ModemUSB() {
|
||||
ampmodem_destroy(demodAM_USB);
|
||||
}
|
||||
|
||||
int ModemUSB::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
if (sampleRate % 2 == 0) {
|
||||
return sampleRate;
|
||||
}
|
||||
return sampleRate+1;
|
||||
}
|
||||
|
||||
void ModemUSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *akit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
@ -7,6 +7,7 @@ public:
|
||||
~ModemUSB();
|
||||
std::string getName();
|
||||
Modem *factory();
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
62
src/modules/modem/digital/ModemFSK.cpp
Normal file
62
src/modules/modem/digital/ModemFSK.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "ModemFSK.h"
|
||||
|
||||
ModemFSK::ModemFSK() {
|
||||
demodulatorCons.store(2);
|
||||
currentDemodCons.store(0);
|
||||
updateDemodulatorCons(2);
|
||||
}
|
||||
|
||||
Modem *ModemFSK::factory() {
|
||||
return new ModemFSK;
|
||||
}
|
||||
|
||||
ModemKit *ModemFSK::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKitFSK *dkit = new ModemKitFSK;
|
||||
dkit->m = 1;
|
||||
dkit->k = sampleRate / 9600;
|
||||
dkit->bandwidth = 7000.0 / sampleRate;
|
||||
|
||||
dkit->demodFSK = fskdem_create(dkit->m, dkit->k, dkit->bandwidth);
|
||||
|
||||
dkit->sampleRate = sampleRate;
|
||||
dkit->audioSampleRate = audioSampleRate;
|
||||
|
||||
return dkit;
|
||||
}
|
||||
|
||||
void ModemFSK::disposeKit(ModemKit *kit) {
|
||||
ModemKitFSK *dkit = (ModemKitFSK *)kit;
|
||||
|
||||
delete dkit;
|
||||
}
|
||||
|
||||
std::string ModemFSK::getName() {
|
||||
return "FSK";
|
||||
}
|
||||
|
||||
ModemFSK::~ModemFSK() {
|
||||
|
||||
}
|
||||
|
||||
void ModemFSK::updateDemodulatorCons(int cons) {
|
||||
|
||||
}
|
||||
|
||||
void ModemFSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitFSK *dkit = (ModemKitFSK *)kit;
|
||||
|
||||
digitalStart(dkit, nullptr, input);
|
||||
|
||||
dkit->inputBuffer.insert(dkit->inputBuffer.end(),input->data.begin(),input->data.end());
|
||||
|
||||
while (dkit->inputBuffer.size() >= dkit->k) {
|
||||
unsigned int sym_out;
|
||||
|
||||
sym_out = fskdem_demodulate(dkit->demodFSK, &dkit->inputBuffer[0]);
|
||||
// std::cout << "ferror: " << fskdem_get_frequency_error(dkit->demodFSK) << std::endl;
|
||||
printf("%01X", sym_out);
|
||||
dkit->inputBuffer.erase(dkit->inputBuffer.begin(),dkit->inputBuffer.begin()+dkit->k);
|
||||
}
|
||||
|
||||
digitalFinish(dkit, nullptr);
|
||||
}
|
29
src/modules/modem/digital/ModemFSK.h
Normal file
29
src/modules/modem/digital/ModemFSK.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "ModemDigital.h"
|
||||
|
||||
class ModemKitFSK : public ModemKitDigital {
|
||||
public:
|
||||
float sps, spacing, bandwidth;
|
||||
unsigned int m, k;
|
||||
|
||||
fskdem demodFSK;
|
||||
std::vector<liquid_float_complex> inputBuffer;
|
||||
};
|
||||
|
||||
|
||||
class ModemFSK : public ModemDigital {
|
||||
public:
|
||||
ModemFSK();
|
||||
~ModemFSK();
|
||||
std::string getName();
|
||||
Modem *factory();
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
void updateDemodulatorCons(int cons);
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
|
||||
private:
|
||||
fskdem dem;
|
||||
};
|
||||
|
@ -461,7 +461,7 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||
bwDiff = -bwDiff;
|
||||
}
|
||||
|
||||
int currentBW = demod->getBandwidth();
|
||||
int currentBW = dragBW;
|
||||
|
||||
currentBW = currentBW + bwDiff;
|
||||
if (currentBW > CHANNELIZER_RATE_MAX) {
|
||||
@ -472,6 +472,7 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||
}
|
||||
|
||||
demod->setBandwidth(currentBW);
|
||||
dragBW = currentBW;
|
||||
}
|
||||
|
||||
if (dragState == WF_DRAG_FREQUENCY) {
|
||||
@ -601,6 +602,7 @@ void WaterfallCanvas::OnMouseDown(wxMouseEvent& event) {
|
||||
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator();
|
||||
if (demod) {
|
||||
dragOfs = (long long) (mouseTracker.getMouseX() * (float) getBandwidth()) + getCenterFrequency() - (getBandwidth() / 2) - demod->getFrequency();
|
||||
dragBW = demod->getBandwidth();
|
||||
}
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getActiveDemodulator(), false);
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ private:
|
||||
float hoverAlpha;
|
||||
int linesPerSecond;
|
||||
float scaleMove;
|
||||
int dragBW;
|
||||
|
||||
SpectrumVisualDataQueue visualDataQueue;
|
||||
Timer gTimer;
|
||||
|
Loading…
Reference in New Issue
Block a user