mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2026-06-01 21:54:39 -04: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:
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user