2017-01-02 21:07:43 -05:00
|
|
|
// Copyright (c) Charles J. Cliffe
|
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
|
2015-11-30 21:58:54 -05:00
|
|
|
#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";
|
|
|
|
}
|
|
|
|
|
2016-07-24 15:25:17 -04:00
|
|
|
ModemBase *ModemGMSK::factory() {
|
2015-11-30 21:58:54 -05:00
|
|
|
return new ModemGMSK;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ModemGMSK::checkSampleRate(long long sampleRate, int audioSampleRate) {
|
2015-12-01 00:59:11 -05:00
|
|
|
if (sampleRate < MIN_BANDWIDTH) {
|
|
|
|
return MIN_BANDWIDTH;
|
2015-11-30 21:58:54 -05:00
|
|
|
}
|
|
|
|
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;
|
2016-02-04 18:05:33 -05:00
|
|
|
for (size_t i = 0, iMax = dkit->inputBuffer.size()/dkit->sps; i < iMax; i+= dkit->sps) {
|
2015-11-30 21:58:54 -05:00
|
|
|
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);
|
2016-02-04 18:05:33 -05:00
|
|
|
}
|