Added M17 decoder module (unfinished)

This commit is contained in:
AlexandreRouma
2021-09-27 03:42:26 +02:00
parent c9a78d5dc6
commit 187fc2cb9e
9 changed files with 951 additions and 16 deletions

View File

@ -73,4 +73,74 @@ namespace dsp {
};
class DCBlocker : public generic_block<DCBlocker> {
public:
DCBlocker() {}
DCBlocker(stream<float>* in, float rate) { init(in, rate); }
void init(stream<float>* in, float rate) {
_in = in;
correctionRate = rate;
offset = 0;
generic_block<DCBlocker>::registerInput(_in);
generic_block<DCBlocker>::registerOutput(&out);
generic_block<DCBlocker>::_block_init = true;
}
void setInput(stream<float>* in) {
assert(generic_block<DCBlocker>::_block_init);
std::lock_guard<std::mutex> lck(generic_block<DCBlocker>::ctrlMtx);
generic_block<DCBlocker>::tempStop();
generic_block<DCBlocker>::unregisterInput(_in);
_in = in;
generic_block<DCBlocker>::registerInput(_in);
generic_block<DCBlocker>::tempStart();
}
void setCorrectionRate(float rate) {
correctionRate = rate;
}
int run() {
int count = _in->read();
if (count < 0) { return -1; }
if (bypass) {
memcpy(out.writeBuf, _in->readBuf, count * sizeof(complex_t));
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
}
for (int i = 0; i < count; i++) {
out.writeBuf[i] = _in->readBuf[i] - offset;
offset = offset + (out.writeBuf[i] * correctionRate);
}
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
}
stream<float> out;
// TEMPORARY FOR DEBUG PURPOSES
bool bypass = false;
float offset;
private:
stream<float>* _in;
float correctionRate = 0.00001;
};
}

View File

@ -11,6 +11,7 @@
#include <dsp/conversion.h>
#include <dsp/audio.h>
#include <dsp/stereo_fm.h>
#include <dsp/correction.h>
#define FAST_ATAN2_COEF1 FL_M_PI / 4.0f
#define FAST_ATAN2_COEF2 3.0f * FAST_ATAN2_COEF1
@ -371,11 +372,11 @@ namespace dsp {
};
class MSKDemod : public generic_hier_block<MSKDemod> {
class FSKDemod : public generic_hier_block<FSKDemod> {
public:
MSKDemod() {}
FSKDemod() {}
MSKDemod(stream<complex_t>* input, float sampleRate, float deviation, float baudRate, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
FSKDemod(stream<complex_t>* input, float sampleRate, float deviation, float baudRate, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
init(input, sampleRate, deviation, baudRate, omegaGain, muGain, omegaRelLimit);
}
@ -391,47 +392,47 @@ namespace dsp {
recov.init(&demod.out, _sampleRate / _baudRate, _omegaGain, _muGain, _omegaRelLimit);
out = &recov.out;
generic_hier_block<MSKDemod>::registerBlock(&demod);
generic_hier_block<MSKDemod>::registerBlock(&recov);
generic_hier_block<MSKDemod>::_block_init = true;
generic_hier_block<FSKDemod>::registerBlock(&demod);
generic_hier_block<FSKDemod>::registerBlock(&recov);
generic_hier_block<FSKDemod>::_block_init = true;
}
void setInput(stream<complex_t>* input) {
assert((generic_hier_block<MSKDemod>::_block_init));
assert((generic_hier_block<FSKDemod>::_block_init));
demod.setInput(input);
}
void setSampleRate(float sampleRate) {
assert(generic_hier_block<MSKDemod>::_block_init);
generic_hier_block<MSKDemod>::tempStop();
assert(generic_hier_block<FSKDemod>::_block_init);
generic_hier_block<FSKDemod>::tempStop();
_sampleRate = sampleRate;
demod.setSampleRate(_sampleRate);
recov.setOmega(_sampleRate / _baudRate, _omegaRelLimit);
generic_hier_block<MSKDemod>::tempStart();
generic_hier_block<FSKDemod>::tempStart();
}
void setDeviation(float deviation) {
assert(generic_hier_block<MSKDemod>::_block_init);
assert(generic_hier_block<FSKDemod>::_block_init);
_deviation = deviation;
demod.setDeviation(deviation);
}
void setBaudRate(float baudRate, float omegaRelLimit) {
assert(generic_hier_block<MSKDemod>::_block_init);
assert(generic_hier_block<FSKDemod>::_block_init);
_baudRate = baudRate;
_omegaRelLimit = omegaRelLimit;
recov.setOmega(_sampleRate / _baudRate, _omegaRelLimit);
}
void setMMGains(float omegaGain, float myGain) {
assert(generic_hier_block<MSKDemod>::_block_init);
assert(generic_hier_block<FSKDemod>::_block_init);
_omegaGain = omegaGain;
_muGain = myGain;
recov.setGains(_omegaGain, _muGain);
}
void setOmegaRelLimit(float omegaRelLimit) {
assert(generic_hier_block<MSKDemod>::_block_init);
assert(generic_hier_block<FSKDemod>::_block_init);
_omegaRelLimit = omegaRelLimit;
recov.setOmegaRelLimit(_omegaRelLimit);
}
@ -450,6 +451,105 @@ namespace dsp {
float _omegaRelLimit;
};
class GFSKDemod : public generic_hier_block<GFSKDemod> {
public:
GFSKDemod() {}
GFSKDemod(stream<complex_t>* input, float sampleRate, float deviation, float rrcAlpha, float baudRate, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
init(input, sampleRate, deviation, rrcAlpha, baudRate, omegaGain, muGain, omegaRelLimit);
}
void init(stream<complex_t>* input, float sampleRate, float deviation, float rrcAlpha, float baudRate, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
_sampleRate = sampleRate;
_deviation = deviation;
_rrcAlpha = rrcAlpha;
_baudRate = baudRate;
_omegaGain = omegaGain;
_muGain = muGain;
_omegaRelLimit = omegaRelLimit;
demod.init(input, _sampleRate, _deviation);
rrc.init(31, _sampleRate, _baudRate, _rrcAlpha);
fir.init(&demod.out, &rrc);
recov.init(&fir.out, _sampleRate / _baudRate, _omegaGain, _muGain, _omegaRelLimit);
out = &recov.out;
generic_hier_block<GFSKDemod>::registerBlock(&demod);
generic_hier_block<GFSKDemod>::registerBlock(&fir);
generic_hier_block<GFSKDemod>::registerBlock(&recov);
generic_hier_block<GFSKDemod>::_block_init = true;
}
void setInput(stream<complex_t>* input) {
assert((generic_hier_block<GFSKDemod>::_block_init));
demod.setInput(input);
}
void setSampleRate(float sampleRate) {
assert(generic_hier_block<GFSKDemod>::_block_init);
generic_hier_block<GFSKDemod>::tempStop();
_sampleRate = sampleRate;
demod.setSampleRate(_sampleRate);
recov.setOmega(_sampleRate / _baudRate, _omegaRelLimit);
rrc.setSampleRate(_sampleRate);
fir.updateWindow(&rrc);
generic_hier_block<GFSKDemod>::tempStart();
}
void setDeviation(float deviation) {
assert(generic_hier_block<GFSKDemod>::_block_init);
_deviation = deviation;
demod.setDeviation(deviation);
}
void setRRCAlpha(float rrcAlpha) {
assert(generic_hier_block<GFSKDemod>::_block_init);
_rrcAlpha = rrcAlpha;
rrc.setAlpha(_rrcAlpha);
fir.updateWindow(&rrc);
}
void setBaudRate(float baudRate, float omegaRelLimit) {
assert(generic_hier_block<GFSKDemod>::_block_init);
_baudRate = baudRate;
_omegaRelLimit = omegaRelLimit;
generic_hier_block<GFSKDemod>::tempStop();
recov.setOmega(_sampleRate / _baudRate, _omegaRelLimit);
rrc.setBaudRate(_baudRate);
fir.updateWindow(&rrc);
generic_hier_block<GFSKDemod>::tempStart();
}
void setMMGains(float omegaGain, float myGain) {
assert(generic_hier_block<GFSKDemod>::_block_init);
_omegaGain = omegaGain;
_muGain = myGain;
recov.setGains(_omegaGain, _muGain);
}
void setOmegaRelLimit(float omegaRelLimit) {
assert(generic_hier_block<GFSKDemod>::_block_init);
_omegaRelLimit = omegaRelLimit;
recov.setOmegaRelLimit(_omegaRelLimit);
}
stream<float>* out = NULL;
private:
FloatFMDemod demod;
RRCTaps rrc;
FIR<float> fir;
MMClockRecovery<float> recov;
float _sampleRate;
float _deviation;
float _rrcAlpha;
float _baudRate;
float _omegaGain;
float _muGain;
float _omegaRelLimit;
};
template<int ORDER, bool OFFSET>
class PSKDemod : public generic_hier_block<PSKDemod<ORDER, OFFSET>> {
public:

View File

@ -65,6 +65,54 @@ namespace dsp {
};
template <class T>
class StreamDoubler : public generic_block<StreamDoubler<T>> {
public:
StreamDoubler() {}
StreamDoubler(stream<T>* in) { init(in); }
void init(stream<T>* in) {
_in = in;
generic_block<StreamDoubler>::registerInput(_in);
generic_block<StreamDoubler>::registerOutput(&outA);
generic_block<StreamDoubler>::registerOutput(&outB);
generic_block<StreamDoubler>::_block_init = true;
}
void setInput(stream<T>* in) {
assert(generic_block<StreamDoubler>::_block_init);
std::lock_guard<std::mutex> lck(generic_block<StreamDoubler>::ctrlMtx);
generic_block<StreamDoubler>::tempStop();
generic_block<StreamDoubler>::unregisterInput(_in);
_in = in;
generic_block<StreamDoubler>::registerInput(_in);
generic_block<StreamDoubler>::tempStart();
}
stream<T> outA;
stream<T> outB;
private:
int run() {
int count = _in->read();
if (count < 0) { return -1; }
memcpy(outA.writeBuf, _in->readBuf, count * sizeof(T));
memcpy(outB.writeBuf, _in->readBuf, count * sizeof(T));
_in->flush();
if (!outA.swap(count)) { return -1; }
if (!outB.swap(count)) { return -1; }
return count;
}
stream<T>* _in;
};
// NOTE: I'm not proud of this, it's BAD and just taken from the previous DSP, but it works...
template <class T>