mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2026-06-01 21:54:39 -04:00
Add GMSK, fix modem bandwidth logic, cleanup.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
#include "Modem.h"
|
||||
#include "CubicSDR.h"
|
||||
|
||||
|
||||
ModemFactoryList Modem::modemFactories;
|
||||
|
||||
@@ -52,12 +54,24 @@ Modem *Modem::makeModem(std::string modemName) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int Modem::getModemDefaultSampleRate(std::string modemName) {
|
||||
if (modemFactories.find(modemName) != modemFactories.end()) {
|
||||
return modemFactories[modemName]->getDefaultSampleRate();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ModemArgInfoList Modem::getSettings() {
|
||||
ModemArgInfoList args;
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
int Modem::getDefaultSampleRate() {
|
||||
return 200000;
|
||||
}
|
||||
|
||||
void Modem::writeSetting(std::string setting, std::string value) {
|
||||
// ...
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@ public:
|
||||
static ModemFactoryList getFactories();
|
||||
|
||||
static Modem *makeModem(std::string modemName);
|
||||
static int getModemDefaultSampleRate(std::string modemName);
|
||||
|
||||
virtual std::string getType() = 0;
|
||||
virtual std::string getName() = 0;
|
||||
@@ -123,6 +124,7 @@ public:
|
||||
virtual ~Modem();
|
||||
|
||||
virtual ModemArgInfoList getSettings();
|
||||
virtual int getDefaultSampleRate();
|
||||
virtual void writeSetting(std::string setting, std::string value);
|
||||
virtual void writeSettings(ModemSettings settings);
|
||||
virtual std::string readSetting(std::string setting);
|
||||
|
||||
@@ -4,6 +4,10 @@ ModemAM::ModemAM() : ModemAnalog() {
|
||||
demodAM = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 0);
|
||||
}
|
||||
|
||||
ModemAM::~ModemAM() {
|
||||
ampmodem_destroy(demodAM);
|
||||
}
|
||||
|
||||
Modem *ModemAM::factory() {
|
||||
return new ModemAM;
|
||||
}
|
||||
@@ -12,6 +16,10 @@ std::string ModemAM::getName() {
|
||||
return "AM";
|
||||
}
|
||||
|
||||
int ModemAM::getDefaultSampleRate() {
|
||||
return 6000;
|
||||
}
|
||||
|
||||
void ModemAM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *amkit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
||||
@@ -5,8 +5,14 @@
|
||||
class ModemAM : public ModemAnalog {
|
||||
public:
|
||||
ModemAM();
|
||||
~ModemAM();
|
||||
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int getDefaultSampleRate();
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
@@ -4,6 +4,10 @@ ModemDSB::ModemDSB() : ModemAnalog() {
|
||||
demodAM_DSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 1);
|
||||
}
|
||||
|
||||
ModemDSB::~ModemDSB() {
|
||||
ampmodem_destroy(demodAM_DSB);
|
||||
}
|
||||
|
||||
Modem *ModemDSB::factory() {
|
||||
return new ModemDSB;
|
||||
}
|
||||
@@ -12,6 +16,10 @@ std::string ModemDSB::getName() {
|
||||
return "DSB";
|
||||
}
|
||||
|
||||
int ModemDSB::getDefaultSampleRate() {
|
||||
return 5400;
|
||||
}
|
||||
|
||||
void ModemDSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *amkit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
||||
@@ -5,8 +5,14 @@
|
||||
class ModemDSB : public ModemAnalog {
|
||||
public:
|
||||
ModemDSB();
|
||||
~ModemDSB();
|
||||
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int getDefaultSampleRate();
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
@@ -4,6 +4,10 @@ ModemFM::ModemFM() : ModemAnalog() {
|
||||
demodFM = freqdem_create(0.5);
|
||||
}
|
||||
|
||||
ModemFM::~ModemFM() {
|
||||
freqdem_destroy(demodFM);
|
||||
}
|
||||
|
||||
Modem *ModemFM::factory() {
|
||||
return new ModemFM;
|
||||
}
|
||||
@@ -12,6 +16,10 @@ std::string ModemFM::getName() {
|
||||
return "FM";
|
||||
}
|
||||
|
||||
int ModemFM::getDefaultSampleRate() {
|
||||
return 200000;
|
||||
}
|
||||
|
||||
void ModemFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *fmkit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
||||
@@ -5,11 +5,16 @@
|
||||
class ModemFM : public ModemAnalog {
|
||||
public:
|
||||
ModemFM();
|
||||
~ModemFM();
|
||||
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int getDefaultSampleRate();
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
freqdem demodFM;
|
||||
};
|
||||
@@ -40,6 +40,10 @@ int ModemFMStereo::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
}
|
||||
}
|
||||
|
||||
int ModemFMStereo::getDefaultSampleRate() {
|
||||
return 200000;
|
||||
}
|
||||
|
||||
ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKitFMStereo *kit = new ModemKitFMStereo;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
Modem *factory();
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
int getDefaultSampleRate();
|
||||
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
|
||||
@@ -4,6 +4,14 @@ ModemIQ::ModemIQ() {
|
||||
|
||||
}
|
||||
|
||||
std::string ModemIQ::getType() {
|
||||
return "analog";
|
||||
}
|
||||
|
||||
std::string ModemIQ::getName() {
|
||||
return "I/Q";
|
||||
}
|
||||
|
||||
Modem *ModemIQ::factory() {
|
||||
return new ModemIQ;
|
||||
}
|
||||
@@ -15,14 +23,6 @@ ModemKit *ModemIQ::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
return kit;
|
||||
}
|
||||
|
||||
std::string ModemIQ::getType() {
|
||||
return "analog";
|
||||
}
|
||||
|
||||
std::string ModemIQ::getName() {
|
||||
return "I/Q";
|
||||
}
|
||||
|
||||
void ModemIQ::disposeKit(ModemKit *kit) {
|
||||
delete kit;
|
||||
}
|
||||
@@ -31,6 +31,10 @@ int ModemIQ::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
return audioSampleRate;
|
||||
}
|
||||
|
||||
int ModemIQ::getDefaultSampleRate() {
|
||||
return 48000;
|
||||
}
|
||||
|
||||
void ModemIQ::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
int bufSize = input->data.size();
|
||||
|
||||
|
||||
@@ -4,12 +4,19 @@
|
||||
class ModemIQ : public Modem {
|
||||
public:
|
||||
ModemIQ();
|
||||
|
||||
std::string getType();
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
int getDefaultSampleRate();
|
||||
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
|
||||
void disposeKit(ModemKit *kit);
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
@@ -29,6 +29,10 @@ int ModemLSB::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
return sampleRate+1;
|
||||
}
|
||||
|
||||
int ModemLSB::getDefaultSampleRate() {
|
||||
return 5400;
|
||||
}
|
||||
|
||||
void ModemLSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *akit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
#pragma once
|
||||
#include "Modem.h"
|
||||
#include "ModemAnalog.h"
|
||||
|
||||
class ModemLSB : public ModemAnalog {
|
||||
public:
|
||||
ModemLSB();
|
||||
~ModemLSB();
|
||||
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
int getDefaultSampleRate();
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
@@ -29,6 +29,10 @@ int ModemUSB::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
return sampleRate+1;
|
||||
}
|
||||
|
||||
int ModemUSB::getDefaultSampleRate() {
|
||||
return 5400;
|
||||
}
|
||||
|
||||
void ModemUSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitAnalog *akit = (ModemKitAnalog *)kit;
|
||||
|
||||
|
||||
@@ -5,9 +5,14 @@ class ModemUSB : public ModemAnalog {
|
||||
public:
|
||||
ModemUSB();
|
||||
~ModemUSB();
|
||||
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
int getDefaultSampleRate();
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,6 +22,10 @@ int ModemFSK::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
}
|
||||
}
|
||||
|
||||
int ModemFSK::getDefaultSampleRate() {
|
||||
return 19200;
|
||||
}
|
||||
|
||||
ModemArgInfoList ModemFSK::getSettings() {
|
||||
ModemArgInfoList args;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
Modem *factory();
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
int getDefaultSampleRate();
|
||||
|
||||
ModemArgInfoList getSettings();
|
||||
void writeSetting(std::string setting, std::string value);
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "ModemGMSK.h"
|
||||
#include <iomanip>
|
||||
|
||||
ModemGMSK::ModemGMSK() : ModemDigital() {
|
||||
_sps = 4;
|
||||
_fdelay = 3;
|
||||
_ebf = 0.3;
|
||||
outStream << std::hex;
|
||||
}
|
||||
|
||||
ModemGMSK::~ModemGMSK() {
|
||||
|
||||
}
|
||||
|
||||
std::string ModemGMSK::getName() {
|
||||
return "GMSK";
|
||||
}
|
||||
|
||||
Modem *ModemGMSK::factory() {
|
||||
return new ModemGMSK;
|
||||
}
|
||||
|
||||
int ModemGMSK::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
if (sampleRate < 1500) {
|
||||
return 1500;
|
||||
}
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
int ModemGMSK::getDefaultSampleRate() {
|
||||
return 19200;
|
||||
}
|
||||
|
||||
ModemArgInfoList ModemGMSK::getSettings() {
|
||||
ModemArgInfoList args;
|
||||
|
||||
ModemArgInfo fdelayArg;
|
||||
fdelayArg.key = "fdelay";
|
||||
fdelayArg.name = "Filter delay";
|
||||
fdelayArg.value = std::to_string(_fdelay);
|
||||
fdelayArg.description = "Filter delay in samples";
|
||||
fdelayArg.type = ModemArgInfo::INT;
|
||||
fdelayArg.units = "samples";
|
||||
fdelayArg.range = ModemRange(1,128);
|
||||
args.push_back(fdelayArg);
|
||||
|
||||
ModemArgInfo spsArg;
|
||||
spsArg.key = "sps";
|
||||
spsArg.name = "Samples / symbol";
|
||||
spsArg.value = std::to_string(_sps);
|
||||
spsArg.description = "Modem samples-per-symbol";
|
||||
spsArg.type = ModemArgInfo::INT;
|
||||
spsArg.units = "samples/symbol";
|
||||
spsArg.range = ModemRange(2,512);
|
||||
args.push_back(spsArg);
|
||||
|
||||
ModemArgInfo ebfArg;
|
||||
ebfArg.key = "ebf";
|
||||
ebfArg.name = "Excess bandwidth";
|
||||
ebfArg.value = std::to_string(_ebf);
|
||||
ebfArg.description = "Modem excess bandwidth factor";
|
||||
ebfArg.type = ModemArgInfo::FLOAT;
|
||||
ebfArg.range = ModemRange(0.1,0.49);
|
||||
args.push_back(ebfArg);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
void ModemGMSK::writeSetting(std::string setting, std::string value) {
|
||||
if (setting == "fdelay") {
|
||||
_fdelay = std::stoi(value);
|
||||
rebuildKit();
|
||||
} else if (setting == "sps") {
|
||||
_sps = std::stoi(value);
|
||||
rebuildKit();
|
||||
} else if (setting == "ebf") {
|
||||
_ebf = std::stof(value);
|
||||
rebuildKit();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ModemGMSK::readSetting(std::string setting) {
|
||||
if (setting == "fdelay") {
|
||||
return std::to_string(_fdelay);
|
||||
} else if (setting == "sps") {
|
||||
return std::to_string(_sps);
|
||||
} else if (setting == "ebf") {
|
||||
return std::to_string(_ebf);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
ModemKit *ModemGMSK::buildKit(long long sampleRate, int audioSampleRate) {
|
||||
ModemKitGMSK *dkit = new ModemKitGMSK;
|
||||
dkit->sps = _sps;
|
||||
dkit->fdelay = _fdelay;
|
||||
dkit->ebf = _ebf;
|
||||
|
||||
dkit->demodGMSK = gmskdem_create(dkit->sps, dkit->fdelay, dkit->ebf);
|
||||
|
||||
dkit->sampleRate = sampleRate;
|
||||
dkit->audioSampleRate = audioSampleRate;
|
||||
|
||||
return dkit;
|
||||
}
|
||||
|
||||
void ModemGMSK::disposeKit(ModemKit *kit) {
|
||||
ModemKitGMSK *dkit = (ModemKitGMSK *)kit;
|
||||
|
||||
gmskdem_destroy(dkit->demodGMSK);
|
||||
|
||||
delete dkit;
|
||||
}
|
||||
|
||||
void ModemGMSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitGMSK *dkit = (ModemKitGMSK *)kit;
|
||||
unsigned int sym_out;
|
||||
|
||||
digitalStart(dkit, nullptr, input);
|
||||
|
||||
dkit->inputBuffer.insert(dkit->inputBuffer.end(),input->data.begin(),input->data.end());
|
||||
|
||||
int numProcessed = 0;
|
||||
for (int i = 0, iMax = dkit->inputBuffer.size()/dkit->sps; i < iMax; i+= dkit->sps) {
|
||||
gmskdem_demodulate(dkit->demodGMSK, &input->data[i],&sym_out);
|
||||
outStream << sym_out;
|
||||
numProcessed += dkit->sps;
|
||||
}
|
||||
|
||||
dkit->inputBuffer.erase(dkit->inputBuffer.begin(),dkit->inputBuffer.begin()+numProcessed);
|
||||
|
||||
digitalFinish(dkit, nullptr);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include "ModemDigital.h"
|
||||
#include <sstream>
|
||||
|
||||
class ModemKitGMSK : public ModemKitDigital {
|
||||
public:
|
||||
unsigned int fdelay, sps;
|
||||
float ebf;
|
||||
|
||||
gmskdem demodGMSK;
|
||||
std::vector<liquid_float_complex> inputBuffer;
|
||||
};
|
||||
|
||||
|
||||
class ModemGMSK : public ModemDigital {
|
||||
public:
|
||||
ModemGMSK();
|
||||
~ModemGMSK();
|
||||
|
||||
std::string getName();
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
int getDefaultSampleRate();
|
||||
|
||||
ModemArgInfoList getSettings();
|
||||
void writeSetting(std::string setting, std::string value);
|
||||
std::string readSetting(std::string setting);
|
||||
|
||||
ModemKit *buildKit(long long sampleRate, int audioSampleRate);
|
||||
void disposeKit(ModemKit *kit);
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
int _sps; // samples per symbol
|
||||
int _fdelay; // filter delay
|
||||
float _ebf;
|
||||
};
|
||||
|
||||
@@ -4,10 +4,6 @@ ModemOOK::ModemOOK() : ModemDigital() {
|
||||
demodOOK = modem_create(LIQUID_MODEM_OOK);
|
||||
}
|
||||
|
||||
Modem *ModemOOK::factory() {
|
||||
return new ModemOOK;
|
||||
}
|
||||
|
||||
ModemOOK::~ModemOOK() {
|
||||
modem_destroy(demodOOK);
|
||||
}
|
||||
@@ -16,6 +12,17 @@ std::string ModemOOK::getName() {
|
||||
return "OOK";
|
||||
}
|
||||
|
||||
Modem *ModemOOK::factory() {
|
||||
return new ModemOOK;
|
||||
}
|
||||
|
||||
int ModemOOK::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
||||
if (sampleRate < 100) {
|
||||
return 100;
|
||||
}
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
void ModemOOK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
|
||||
ModemKitDigital *dkit = (ModemKitDigital *)kit;
|
||||
digitalStart(dkit, demodOOK, input);
|
||||
|
||||
@@ -10,6 +10,8 @@ public:
|
||||
|
||||
Modem *factory();
|
||||
|
||||
int checkSampleRate(long long sampleRate, int audioSampleRate);
|
||||
|
||||
void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut);
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user