From 46f17019a7dc826c923e329dcd7bc2552991e457 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sat, 2 Jul 2022 18:30:13 +0200 Subject: [PATCH] cleanup + bugfix --- core/src/dsp/demod/gfsk.h | 162 +++++++++++++++++++++++ core/src/dsp/loop/costas.h | 2 +- decoder_modules/m17_decoder/src/m17dsp.h | 4 +- 3 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 core/src/dsp/demod/gfsk.h diff --git a/core/src/dsp/demod/gfsk.h b/core/src/dsp/demod/gfsk.h new file mode 100644 index 0000000..1287684 --- /dev/null +++ b/core/src/dsp/demod/gfsk.h @@ -0,0 +1,162 @@ +#pragma once +#include "quadrature.h" +#include "../taps/root_raised_cosine.h" +#include "../filter/fir.h" +#include "../clock_recovery/mm.h" + +namespace dsp::demod { + // Note: I don't like how this demodulator reuses 90% of the code from the PSK demod. Same will be for the PM demod... + class GFSK : public Processor { + using base_type = Processor; + public: + GFSK() {} + + GFSK(stream* in, double symbolrate, double samplerate, double deviation, int rrcTapCount, double rrcBeta, double omegaGain, double muGain, double omegaRelLimit = 0.01) { + init(in, symbolrate, samplerate, deviation, rrcTapCount, rrcBeta, omegaGain, muGain); + } + + ~GFSK() { + if (!base_type::_block_init) { return; } + base_type::stop(); + taps::free(rrcTaps); + } + + void init(stream* in, double symbolrate, double samplerate, double deviation, int rrcTapCount, double rrcBeta, double omegaGain, double muGain, double omegaRelLimit = 0.01) { + _symbolrate = symbolrate; + _samplerate = samplerate; + _deviation = deviation; + _rrcTapCount = rrcTapCount; + _rrcBeta = rrcBeta; + + demod.init(NULL, _deviation, _samplerate); + rrcTaps = taps::rootRaisedCosine(_rrcTapCount, _rrcBeta, _symbolrate, _samplerate); + rrc.init(NULL, rrcTaps); + recov.init(NULL, _samplerate / _symbolrate, omegaGain, muGain, omegaRelLimit); + + demod.out.free(); + rrc.out.free(); + recov.out.free(); + + base_type::init(in); + } + + void setSymbolrate(double symbolrate) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _symbolrate = symbolrate; + taps::free(rrcTaps); + rrcTaps = taps::rootRaisedCosine(_rrcTapCount, _rrcBeta, _symbolrate, _samplerate); + rrc.setTaps(rrcTaps); + recov.setOmega(_samplerate / _symbolrate); + base_type::tempStart(); + } + + void setSamplerate(double samplerate) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _samplerate = samplerate; + demod.setDeviation(_deviation, _samplerate); + taps::free(rrcTaps); + rrcTaps = taps::rootRaisedCosine(_rrcTapCount, _rrcBeta, _symbolrate, _samplerate); + rrc.setTaps(rrcTaps); + recov.setOmega(_samplerate / _symbolrate); + base_type::tempStart(); + } + + void setDeviation(double deviation) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + _deviation = deviation; + demod.setDeviation(_deviation, _samplerate); + } + + void setRRCParams(int rrcTapCount, double rrcBeta) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + _rrcTapCount = rrcTapCount; + _rrcBeta = rrcBeta; + taps::free(rrcTaps); + rrcTaps = taps::rootRaisedCosine(_rrcTapCount, _rrcBeta, _symbolrate, _samplerate); + base_type::tempStart(); + } + + void setRRCTapCount(int rrcTapCount) { + setRRCParams(rrcTapCount, _rrcBeta); + } + + void setRRCBeta(int rrcBeta) { + setRRCParams(_rrcTapCount, rrcBeta); + } + + void setMMParams(double omegaGain, double muGain, double omegaRelLimit = 0.01) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + recov.setOmegaGain(omegaGain); + recov.setMuGain(muGain); + recov.setOmegaRelLimit(omegaRelLimit); + } + + void setOmegaGain(double omegaGain) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + recov.setOmegaGain(omegaGain); + } + + void setMuGain(double muGain) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + recov.setMuGain(muGain); + } + + void setOmegaRelLimit(double omegaRelLimit) { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + recov.setOmegaRelLimit(omegaRelLimit); + } + + void reset() { + assert(base_type::_block_init); + std::lock_guard lck(base_type::ctrlMtx); + base_type::tempStop(); + demod.reset(); + rrc.reset(); + recov.reset(); + base_type::tempStart(); + } + + inline int process(int count, complex_t* in, float* out) { + demod.process(count, in, out); + rrc.process(count, out, out); + return recov.process(count, out, out); + } + + int run() { + int count = base_type::_in->read(); + if (count < 0) { return -1; } + + int outCount = process(count, base_type::_in->readBuf, base_type::out.writeBuf); + + // Swap if some data was generated + base_type::_in->flush(); + if (outCount) { + if (!base_type::out.swap(outCount)) { return -1; } + } + return outCount; + } + + protected: + double _symbolrate; + double _samplerate; + double _deviation; + int _rrcTapCount; + double _rrcBeta; + + Quadrature demod; + tap rrcTaps; + filter::FIR rrc; + clock_recovery::MM recov; + }; +} \ No newline at end of file diff --git a/core/src/dsp/loop/costas.h b/core/src/dsp/loop/costas.h index 2947564..6287461 100644 --- a/core/src/dsp/loop/costas.h +++ b/core/src/dsp/loop/costas.h @@ -28,7 +28,7 @@ namespace dsp::loop { if constexpr (ORDER == 8) { // The way this works is it compresses order 4 constellations into the quadrants const float K = sqrtf(2.0) - 1.0; - if (fabsf(outVal.re) >= fabsf(outVal.im)) { + if (fabsf(val.re) >= fabsf(val.im)) { err = (math::step(val.re) * val.im) - (math::step(val.im) * val.re * K); } else { diff --git a/decoder_modules/m17_decoder/src/m17dsp.h b/decoder_modules/m17_decoder/src/m17dsp.h index 577650e..96398b1 100644 --- a/decoder_modules/m17_decoder/src/m17dsp.h +++ b/decoder_modules/m17_decoder/src/m17dsp.h @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -641,7 +641,7 @@ namespace dsp { stream* out = NULL; private: - demod::GMSK demod; + demod::GFSK demod; routing::Doubler doubler; M17Slice4FSK slice; M17FrameDemux demux;