Formatted the entire codebase and added a CI check for formatting

This commit is contained in:
AlexandreRouma
2021-12-19 22:11:44 +01:00
parent 8644957881
commit ea587db0cb
161 changed files with 3302 additions and 3393 deletions

View File

@ -40,7 +40,6 @@ namespace dsp {
private:
stream<float>* _in;
};
class ChannelsToStereo : public generic_block<ChannelsToStereo> {
@ -98,7 +97,6 @@ namespace dsp {
stream<float>* _in_right;
float* nullbuf;
};
class StereoToMono : public generic_block<StereoToMono> {
@ -151,9 +149,8 @@ namespace dsp {
stream<float> out;
private:
float* l_buf, *r_buf;
float *l_buf, *r_buf;
stream<stereo_t>* _in;
};
class StereoToChannels : public generic_block<StereoToChannels> {
@ -197,6 +194,5 @@ namespace dsp {
private:
stream<stereo_t>* _in;
};
}

View File

@ -17,7 +17,7 @@ namespace dsp {
virtual int calcOutSize(int inSize) { return inSize; }
virtual int run() { return -1; }
};
template <class BLOCK>
class generic_block : public generic_unnamed_block {
public:
@ -71,12 +71,12 @@ namespace dsp {
}
virtual int run() = 0;
friend BLOCK;
private:
void workerLoop() {
while (run() >= 0);
void workerLoop() {
while (run() >= 0) {}
}
void acquire() {
@ -139,7 +139,6 @@ namespace dsp {
bool running = false;
bool tempStopped = false;
std::thread workerThread;
};
template <class BLOCK>
@ -224,6 +223,5 @@ namespace dsp {
protected:
bool _block_init = false;
std::mutex ctrlMtx;
};
}

View File

@ -47,7 +47,7 @@ namespace dsp {
else {
memcpy(&data[dataRead], &_buffer[readc], toRead * sizeof(T));
}
dataRead += toRead;
_readable_mtx.lock();
@ -114,7 +114,7 @@ namespace dsp {
int _r = getReadable();
if (_r != 0) { return _r; }
std::unique_lock<std::mutex> lck(_readable_mtx);
canReadVar.wait(lck, [=](){ return ((this->getReadable(false) > 0) || this->getReadStop()); });
canReadVar.wait(lck, [=]() { return ((this->getReadable(false) > 0) || this->getReadStop()); });
if (_stopReader) { return -1; }
return getReadable(false);
}
@ -152,7 +152,7 @@ namespace dsp {
writable -= toWrite;
_writable_mtx.unlock();
writec = (writec + toWrite) % size;
canReadVar.notify_one();
}
return len;
@ -164,7 +164,7 @@ namespace dsp {
int _w = getWritable();
if (_w != 0) { return _w; }
std::unique_lock<std::mutex> lck(_writable_mtx);
canWriteVar.wait(lck, [=](){ return ((this->getWritable(false) > 0) || this->getWriteStop()); });
canWriteVar.wait(lck, [=]() { return ((this->getWritable(false) > 0) || this->getWriteStop()); });
if (_stopWriter) { return -1; }
return getWritable(false);
}
@ -173,7 +173,10 @@ namespace dsp {
assert(_init);
if (lock) { _writable_mtx.lock(); };
int _w = writable;
if (lock) { _writable_mtx.unlock(); _readable_mtx.lock(); };
if (lock) {
_writable_mtx.unlock();
_readable_mtx.lock();
};
int _r = readable;
if (lock) { _readable_mtx.unlock(); };
return std::max<int>(std::min<int>(_w, maxLatency - _r), 0);
@ -233,7 +236,7 @@ namespace dsp {
std::condition_variable canWriteVar;
};
#define TEST_BUFFER_SIZE 32
#define TEST_BUFFER_SIZE 32
template <class T>
class SampleFrameBuffer : public generic_block<SampleFrameBuffer<T>> {
@ -303,7 +306,7 @@ namespace dsp {
while (true) {
// Wait for data
std::unique_lock lck(bufMtx);
cnd.wait(lck, [this](){ return (((writeCur - readCur + TEST_BUFFER_SIZE) % TEST_BUFFER_SIZE) > 0) || stopWorker; });
cnd.wait(lck, [this]() { return (((writeCur - readCur + TEST_BUFFER_SIZE) % TEST_BUFFER_SIZE) > 0) || stopWorker; });
if (stopWorker) { break; }
// Write one to output buffer and unlock in preparation to swap buffers
@ -315,7 +318,7 @@ namespace dsp {
// Swap
if (!out.swap(count)) { break; }
}
}
}
stream<T> out;
@ -352,8 +355,7 @@ namespace dsp {
std::condition_variable cnd;
T* buffers[TEST_BUFFER_SIZE];
int sizes[TEST_BUFFER_SIZE];
bool stopWorker = false;
bool stopWorker = false;
};
};

View File

@ -20,11 +20,11 @@ namespace dsp {
class ChainLink : public ChainLinkAny<T> {
public:
~ChainLink() {}
void setInput(stream<T>* stream) {
block.setInput(stream);
}
stream<T>* getOutput() {
return &block.out;
}
@ -60,7 +60,7 @@ namespace dsp {
spdlog::error("Could not add new link to the chain, link already in the chain");
return;
}
// Assert that the link is stopped and disabled
link->stop();
link->enabled = false;
@ -85,7 +85,7 @@ namespace dsp {
if (!(*i)->enabled) { continue; }
input = (*i)->getOutput();
}
// Find next block
ChainLinkAny<T>* nextLink = NULL;
for (auto i = ++lnit; i < links.end(); i++) {
@ -127,7 +127,7 @@ namespace dsp {
if (!(*i)->enabled) { continue; }
input = (*i)->getOutput();
}
// Find next block
ChainLinkAny<T>* nextLink = NULL;
for (auto i = ++lnit; i < links.end(); i++) {
@ -157,7 +157,7 @@ namespace dsp {
void setInput(stream<T>* input) {
_input = input;
// Set input of first enabled link
for (auto& ln : links) {
if (!ln->enabled) { continue; }
@ -203,6 +203,5 @@ namespace dsp {
stream<T>* _input;
std::vector<ChainLinkAny<T>*> links;
bool running = false;
};
}

View File

@ -7,7 +7,7 @@ namespace dsp {
class EdgeTrigClockRecovery : public generic_block<EdgeTrigClockRecovery> {
public:
EdgeTrigClockRecovery() {}
EdgeTrigClockRecovery(stream<float>* in, int omega) { init(in, omega); }
void init(stream<float>* in, int omega) {
@ -51,7 +51,7 @@ namespace dsp {
lastVal = _in->readBuf[i];
}
_in->flush();
if (outCount > 0 && !out.swap(outCount)) { return -1; }
return count;
@ -65,10 +65,9 @@ namespace dsp {
int counter = 0;
float lastVal = 0;
stream<float>* _in;
};
template<class T>
template <class T>
class MMClockRecovery : public generic_block<MMClockRecovery<T>> {
public:
MMClockRecovery() {}
@ -146,7 +145,7 @@ namespace dsp {
int i = nextOffset;
for (; i < count && outCount < maxOut;) {
if constexpr (std::is_same_v<T, float>) {
// Calculate output value
// If we still need to use the old values, calculate using delay buf
@ -160,7 +159,7 @@ namespace dsp {
out.writeBuf[outCount++] = outVal;
// Cursed phase detect approximation (don't ask me how this approximation works)
phaseError = (DSP_STEP(lastOutput)*outVal) - (lastOutput*DSP_STEP(outVal));
phaseError = (DSP_STEP(lastOutput) * outVal) - (lastOutput * DSP_STEP(outVal));
lastOutput = outVal;
}
if constexpr (std::is_same_v<T, complex_t> || std::is_same_v<T, stereo_t>) {
@ -195,7 +194,9 @@ namespace dsp {
// TODO: Branchless clamp
_dynOmega = _dynOmega + (_gainOmega * phaseError);
if (_dynOmega > omegaMax) { _dynOmega = omegaMax; }
else if (_dynOmega < omegaMin) { _dynOmega = omegaMin; }
else if (_dynOmega < omegaMin) {
_dynOmega = omegaMin;
}
// Adjust the symbol phase according to the phase error approximation
// It will now contain the phase delta needed to jump to the next symbol
@ -215,7 +216,7 @@ namespace dsp {
// Save the last 7 values for the next round
memcpy(delay, &_in->readBuf[count - 7], 7 * sizeof(T));
_in->flush();
if (outCount > 0 && !out.swap(outCount)) { return -1; }
return count;
@ -246,10 +247,9 @@ namespace dsp {
float lastOutput = 0.0f;
// Cursed complex stuff
complex_t _p_0T = {0,0}, _p_1T = {0,0}, _p_2T = {0,0};
complex_t _c_0T = {0,0}, _c_1T = {0,0}, _c_2T = {0,0};
complex_t _p_0T = { 0, 0 }, _p_1T = { 0, 0 }, _p_2T = { 0, 0 };
complex_t _c_0T = { 0, 0 }, _c_1T = { 0, 0 }, _c_2T = { 0, 0 };
stream<T>* _in;
};
}

View File

@ -83,7 +83,7 @@ namespace dsp {
else {
_in->flush();
}
return count;
}
@ -92,13 +92,12 @@ namespace dsp {
private:
stream<complex_t>* _in;
PCMType _pcmType;
};
class DynamicRangeDecompressor : public generic_block<DynamicRangeDecompressor> {
public:
DynamicRangeDecompressor() {}
DynamicRangeDecompressor(stream<uint8_t>* in) { init(in); }
void init(stream<uint8_t>* in) {
@ -147,8 +146,8 @@ namespace dsp {
volk_16i_s32f_convert_32f((float*)out.writeBuf, (int16_t*)dataBuf, 32768.0f / absScale, outCount * 2);
_in->flush();
if (!out.swap(outCount)) { return -1; }
}
}
return count;
}
@ -156,6 +155,5 @@ namespace dsp {
private:
stream<uint8_t>* _in;
};
}

View File

@ -42,7 +42,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
};
class ComplexToReal : public generic_block<ComplexToReal> {
@ -83,7 +82,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
};
class ComplexToImag : public generic_block<ComplexToImag> {
@ -116,7 +114,7 @@ namespace dsp {
volk_32fc_deinterleave_imag_32f(out.writeBuf, (lv_32fc_t*)_in->readBuf, count);
_in->flush();
if(!out.swap(count)) { return -1; }
if (!out.swap(count)) { return -1; }
return count;
}
@ -124,7 +122,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
};
@ -176,7 +173,6 @@ namespace dsp {
private:
float* nullBuffer;
stream<float>* _in;
};
class Int16CToComplex : public generic_block<Int16CToComplex> {
@ -217,7 +213,6 @@ namespace dsp {
private:
stream<int16_t>* _in;
};
class ComplexToInt16C : public generic_block<ComplexToInt16C> {
@ -258,7 +253,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
};
class Int16ToFloat : public generic_block<Int16ToFloat> {
@ -299,7 +293,6 @@ namespace dsp {
private:
stream<int16_t>* _in;
};
class FloatToInt16 : public generic_block<FloatToInt16> {
@ -340,6 +333,5 @@ namespace dsp {
private:
stream<float>* _in;
};
}

View File

@ -70,8 +70,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
float correctionRate = 0.00001;
};
class DCBlocker : public generic_block<DCBlocker> {
@ -138,9 +136,7 @@ namespace dsp {
private:
stream<float>* _in;
float correctionRate = 0.00001;
};
}

View File

@ -67,14 +67,14 @@ namespace dsp {
int outIndex = 0;
if constexpr (std::is_same_v<T, float>) {
while (inIndex < count) {
volk_32f_x2_dot_prod_32f((float*)&out.writeBuf[outIndex], (float*)&buffer[inIndex+1], taps, tapCount);
volk_32f_x2_dot_prod_32f((float*)&out.writeBuf[outIndex], (float*)&buffer[inIndex + 1], taps, tapCount);
inIndex += 2;
outIndex++;
}
}
if constexpr (std::is_same_v<T, complex_t>) {
while (inIndex < count) {
volk_32fc_32f_dot_prod_32fc((lv_32fc_t*)&out.writeBuf[outIndex], (lv_32fc_t*)&buffer[inIndex+1], taps, tapCount);
volk_32fc_32f_dot_prod_32fc((lv_32fc_t*)&out.writeBuf[outIndex], (lv_32fc_t*)&buffer[inIndex + 1], taps, tapCount);
inIndex += 2;
outIndex++;
}
@ -84,7 +84,7 @@ namespace dsp {
if (!out.swap(outIndex)) { return -1; }
memmove(buffer, &buffer[count], tapCount * sizeof(T));
return count;
}
@ -102,6 +102,5 @@ namespace dsp {
int tapCount;
float* taps;
int _inIndex = 0;
};
}

View File

@ -2,8 +2,8 @@
#include <dsp/block.h>
#include <inttypes.h>
#define DSP_SIGN(n) ((n) >= 0)
#define DSP_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)
#define DSP_SIGN(n) ((n) >= 0)
#define DSP_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)
namespace dsp {
class Deframer : public generic_block<Deframer> {
@ -21,14 +21,14 @@ namespace dsp {
void init(stream<uint8_t>* in, int frameLen, uint8_t* syncWord, int syncLen) {
_in = in;
_frameLen = frameLen;
_syncword = new uint8_t[syncLen];
_syncword = new uint8_t[syncLen];
_syncLen = syncLen;
memcpy(_syncword, syncWord, syncLen);
buffer = new uint8_t[STREAM_BUFFER_SIZE + syncLen];
memset(buffer, 0, syncLen);
bufferStart = buffer + syncLen;
generic_block<Deframer>::registerInput(_in);
generic_block<Deframer>::registerOutput(&out);
generic_block<Deframer>::_block_init = true;
@ -54,7 +54,7 @@ namespace dsp {
// Iterate through all symbols
for (int i = 0; i < count;) {
// If already in the process of reading bits
// If already in the process of reading bits
if (bitsRead >= 0) {
if ((bitsRead % 8) == 0) { out.writeBuf[bitsRead / 8] = 0; }
out.writeBuf[bitsRead / 8] |= (buffer[i] << (7 - (bitsRead % 8)));
@ -80,27 +80,27 @@ namespace dsp {
else if (nextBitIsStartOfFrame) {
nextBitIsStartOfFrame = false;
// try to save
// try to save
if (badFrameCount < 5) {
badFrameCount++;
//printf("Frame found!\n");
bitsRead = 0;
continue;
}
}
else { i++; }
else {
i++;
}
nextBitIsStartOfFrame = false;
}
// Keep last _syncLen4 symbols
memcpy(buffer, &_in->readBuf[count - _syncLen], _syncLen);
//printf("Block processed\n");
callcount++;
callcount++;
_in->flush();
return count;
@ -123,15 +123,14 @@ namespace dsp {
bool nextBitIsStartOfFrame = false;
int callcount = 0;
stream<uint8_t>* _in;
stream<uint8_t>* _in;
};
inline int MachesterHammingDistance(float* data, uint8_t* syncBits, int n) {
int dist = 0;
for (int i = 0; i < n; i++) {
if ((data[(2*i) + 1] > data[2*i]) != syncBits[i]) { dist++; }
if ((data[(2 * i) + 1] > data[2 * i]) != syncBits[i]) { dist++; }
}
return dist;
}
@ -153,14 +152,14 @@ namespace dsp {
void init(stream<float>* in, int frameLen, uint8_t* syncWord, int syncLen) {
_in = in;
_frameLen = frameLen;
_syncword = new uint8_t[syncLen];
_syncword = new uint8_t[syncLen];
_syncLen = syncLen;
memcpy(_syncword, syncWord, syncLen);
buffer = new float[STREAM_BUFFER_SIZE + (syncLen * 2)];
memset(buffer, 0, syncLen * 2 * sizeof(float));
bufferStart = &buffer[syncLen * 2];
generic_block<ManchesterDeframer>::registerInput(_in);
generic_block<ManchesterDeframer>::registerOutput(&out);
generic_block<ManchesterDeframer>::_block_init = true;
@ -188,7 +187,7 @@ namespace dsp {
// Iterate through all symbols
for (int i = 0; i < count;) {
// If already in the process of reading bits
// If already in the process of reading bits
if (bitsRead >= 0) {
readable = std::min<int>(count - i, _frameLen - bitsRead);
memcpy(&out.writeBuf[bitsRead], &buffer[i], readable * sizeof(float));
@ -208,7 +207,6 @@ namespace dsp {
}
i++;
}
// Keep last _syncLen symbols
@ -228,9 +226,8 @@ namespace dsp {
int _frameLen;
int _syncLen;
int bitsRead = -1;
stream<float>* _in;
stream<float>* _in;
};
class SymbolDeframer : public generic_block<SymbolDeframer> {
@ -242,14 +239,14 @@ namespace dsp {
void init(stream<uint8_t>* in, int frameLen, uint8_t* syncWord, int syncLen) {
_in = in;
_frameLen = frameLen;
_syncword = new uint8_t[syncLen];
_syncword = new uint8_t[syncLen];
_syncLen = syncLen;
memcpy(_syncword, syncWord, syncLen);
buffer = new uint8_t[STREAM_BUFFER_SIZE + syncLen];
memset(buffer, 0, syncLen);
bufferStart = &buffer[syncLen];
generic_block<SymbolDeframer>::registerInput(_in);
generic_block<SymbolDeframer>::registerOutput(&out);
generic_block<SymbolDeframer>::_block_init = true;
@ -277,7 +274,7 @@ namespace dsp {
// Iterate through all symbols
for (int i = 0; i < count;) {
// If already in the process of reading bits
// If already in the process of reading bits
if (bitsRead >= 0) {
readable = std::min<int>(count - i, _frameLen - bitsRead);
memcpy(&out.writeBuf[bitsRead], &buffer[i], readable);
@ -297,7 +294,6 @@ namespace dsp {
}
i++;
}
// Keep last _syncLen symbols
@ -317,9 +313,8 @@ namespace dsp {
int _frameLen;
int _syncLen;
int bitsRead = -1;
stream<uint8_t>* _in;
stream<uint8_t>* _in;
};
class ManchesterDecoder : public generic_block<ManchesterDecoder> {
@ -352,12 +347,12 @@ namespace dsp {
if (_inverted) {
for (int i = 0; i < count; i += 2) {
out.writeBuf[i/2] = (_in->readBuf[i + 1] < _in->readBuf[i]);
out.writeBuf[i / 2] = (_in->readBuf[i + 1] < _in->readBuf[i]);
}
}
else {
for (int i = 0; i < count; i += 2) {
out.writeBuf[i/2] = (_in->readBuf[i + 1] > _in->readBuf[i]);
out.writeBuf[i / 2] = (_in->readBuf[i + 1] > _in->readBuf[i]);
}
}
@ -371,7 +366,6 @@ namespace dsp {
private:
stream<float>* _in;
bool _inverted;
};
class BitPacker : public generic_block<BitPacker> {
@ -382,7 +376,7 @@ namespace dsp {
void init(stream<uint8_t>* in) {
_in = in;
generic_block<BitPacker>::registerInput(_in);
generic_block<BitPacker>::registerOutput(&out);
generic_block<BitPacker>::_block_init = true;
@ -415,8 +409,6 @@ namespace dsp {
stream<uint8_t> out;
private:
stream<uint8_t>* _in;
};
}

View File

@ -13,14 +13,14 @@
#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
#define FAST_ATAN2_COEF1 FL_M_PI / 4.0f
#define FAST_ATAN2_COEF2 3.0f * FAST_ATAN2_COEF1
inline float fast_arctan2(float y, float x) {
float abs_y = fabsf(y);
float r, angle;
if (x == 0.0f && y == 0.0f) { return 0.0f; }
if (x>=0.0f) {
if (x >= 0.0f) {
r = (x - abs_y) / (x + abs_y);
angle = FAST_ATAN2_COEF1 - FAST_ATAN2_COEF1 * r;
}
@ -98,8 +98,10 @@ namespace dsp {
for (int i = 0; i < count; i++) {
currentPhase = fast_arctan2(_in->readBuf[i].im, _in->readBuf[i].re);
diff = currentPhase - phase;
if (diff > 3.1415926535f) { diff -= 2 * 3.1415926535f; }
else if (diff <= -3.1415926535f) { diff += 2 * 3.1415926535f; }
if (diff > 3.1415926535f) { diff -= 2 * 3.1415926535f; }
else if (diff <= -3.1415926535f) {
diff += 2 * 3.1415926535f;
}
out.writeBuf[i] = diff / phasorSpeed;
phase = currentPhase;
}
@ -115,7 +117,6 @@ namespace dsp {
float phase = 0;
float phasorSpeed, _sampleRate, _deviation;
stream<complex_t>* _in;
};
class FMDemod : public generic_block<FMDemod> {
@ -179,8 +180,10 @@ namespace dsp {
for (int i = 0; i < count; i++) {
currentPhase = fast_arctan2(_in->readBuf[i].im, _in->readBuf[i].re);
diff = currentPhase - phase;
if (diff > 3.1415926535f) { diff -= 2 * 3.1415926535f; }
else if (diff <= -3.1415926535f) { diff += 2 * 3.1415926535f; }
if (diff > 3.1415926535f) { diff -= 2 * 3.1415926535f; }
else if (diff <= -3.1415926535f) {
diff += 2 * 3.1415926535f;
}
out.writeBuf[i].l = diff / phasorSpeed;
out.writeBuf[i].r = diff / phasorSpeed;
phase = currentPhase;
@ -197,7 +200,6 @@ namespace dsp {
float phase = 0;
float phasorSpeed, _sampleRate, _deviation;
stream<complex_t>* _in;
};
class AMDemod : public generic_block<AMDemod> {
@ -245,7 +247,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
float avg = 0;
};
class SSBDemod : public generic_block<SSBDemod> {
@ -369,25 +370,24 @@ namespace dsp {
lv_32fc_t* buffer;
lv_32fc_t phase;
lv_32fc_t phaseDelta;
};
class FSKDemod : public generic_hier_block<FSKDemod> {
public:
FSKDemod() {}
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) {
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);
}
void init(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) {
void init(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) {
_sampleRate = sampleRate;
_deviation = deviation;
_baudRate = baudRate;
_omegaGain = omegaGain;
_muGain = muGain;
_omegaRelLimit = omegaRelLimit;
demod.init(input, _sampleRate, _deviation);
recov.init(&demod.out, _sampleRate / _baudRate, _omegaGain, _muGain, _omegaRelLimit);
out = &recov.out;
@ -455,11 +455,11 @@ namespace dsp {
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) {
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) {
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;
@ -467,7 +467,7 @@ namespace dsp {
_omegaGain = omegaGain;
_muGain = muGain;
_omegaRelLimit = omegaRelLimit;
demod.init(input, _sampleRate, _deviation);
rrc.init(31, _sampleRate, _baudRate, _rrcAlpha);
fir.init(&demod.out, &rrc);
@ -550,16 +550,16 @@ namespace dsp {
float _omegaRelLimit;
};
template<int ORDER, bool OFFSET>
template <int ORDER, bool OFFSET>
class PSKDemod : public generic_hier_block<PSKDemod<ORDER, OFFSET>> {
public:
PSKDemod() {}
PSKDemod(stream<complex_t>* input, float sampleRate, float baudRate, int RRCTapCount = 31, float RRCAlpha = 0.32f, float agcRate = 10e-4, float costasLoopBw = 0.004f, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
PSKDemod(stream<complex_t>* input, float sampleRate, float baudRate, int RRCTapCount = 31, float RRCAlpha = 0.32f, float agcRate = 10e-4, float costasLoopBw = 0.004f, float omegaGain = (0.01 * 0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
init(input, sampleRate, baudRate, RRCTapCount, RRCAlpha, agcRate, costasLoopBw, omegaGain, muGain, omegaRelLimit);
}
void init(stream<complex_t>* input, float sampleRate, float baudRate, int RRCTapCount = 31, float RRCAlpha = 0.32f, float agcRate = 10e-4, float costasLoopBw = 0.004f, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
void init(stream<complex_t>* input, float sampleRate, float baudRate, int RRCTapCount = 31, float RRCAlpha = 0.32f, float agcRate = 10e-4, float costasLoopBw = 0.004f, float omegaGain = (0.01 * 0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
_RRCTapCount = RRCTapCount;
_RRCAlpha = RRCAlpha;
_sampleRate = sampleRate;
@ -569,7 +569,7 @@ namespace dsp {
_omegaGain = omegaGain;
_muGain = muGain;
_omegaRelLimit = omegaRelLimit;
agc.init(input, 1.0f, 65535, _agcRate);
taps.init(_RRCTapCount, _sampleRate, _baudRate, _RRCAlpha);
rrc.init(&agc.out, &taps);
@ -583,7 +583,7 @@ namespace dsp {
delay.init(&demod.out);
recov.init(&delay.out, _sampleRate / _baudRate, _omegaGain, _muGain, _omegaRelLimit);
generic_hier_block<PSKDemod<ORDER, OFFSET>>::registerBlock(&delay);
}
}
else {
recov.init(&demod.out, _sampleRate / _baudRate, _omegaGain, _muGain, _omegaRelLimit);
}
@ -683,11 +683,11 @@ namespace dsp {
public:
PMDemod() {}
PMDemod(stream<complex_t>* input, float sampleRate, float baudRate, float agcRate = 0.02e-3f, float pllLoopBandwidth = (0.06f*0.06f) / 4.0f, int rrcTapCount = 31, float rrcAlpha = 0.6f, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
PMDemod(stream<complex_t>* input, float sampleRate, float baudRate, float agcRate = 0.02e-3f, float pllLoopBandwidth = (0.06f * 0.06f) / 4.0f, int rrcTapCount = 31, float rrcAlpha = 0.6f, float omegaGain = (0.01 * 0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
init(input, sampleRate, baudRate, agcRate, pllLoopBandwidth, rrcTapCount, rrcAlpha, omegaGain, muGain, omegaRelLimit);
}
void init(stream<complex_t>* input, float sampleRate, float baudRate, float agcRate = 0.02e-3f, float pllLoopBandwidth = (0.06f*0.06f) / 4.0f, int rrcTapCount = 31, float rrcAlpha = 0.6f, float omegaGain = (0.01*0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
void init(stream<complex_t>* input, float sampleRate, float baudRate, float agcRate = 0.02e-3f, float pllLoopBandwidth = (0.06f * 0.06f) / 4.0f, int rrcTapCount = 31, float rrcAlpha = 0.6f, float omegaGain = (0.01 * 0.01) / 4, float muGain = 0.01f, float omegaRelLimit = 0.005f) {
_sampleRate = sampleRate;
_baudRate = baudRate;
_agcRate = agcRate;
@ -697,7 +697,7 @@ namespace dsp {
_omegaGain = omegaGain;
_muGain = muGain;
_omegaRelLimit = omegaRelLimit;
agc.init(input, 1.0f, 65535, _agcRate);
pll.init(&agc.out, _pllLoopBandwidth);
rrcwin.init(_rrcTapCount, _sampleRate, _baudRate, _rrcAlpha);
@ -796,7 +796,7 @@ namespace dsp {
recon.init(&demux.AplusBOut, &demux.AminusBOut);
out = &recon.out;
generic_hier_block<StereoFMDemod>::registerBlock(&demod);
generic_hier_block<StereoFMDemod>::registerBlock(&r2c);
generic_hier_block<StereoFMDemod>::registerBlock(&pilotFilter);

View File

@ -3,37 +3,36 @@
#include <inttypes.h>
// WTF???
extern "C"
{
extern "C" {
#include <correct.h>
}
const uint8_t toDB[] = {
0x00, 0x7b, 0xaf, 0xd4, 0x99, 0xe2, 0x36, 0x4d, 0xfa, 0x81, 0x55, 0x2e, 0x63, 0x18, 0xcc, 0xb7, 0x86, 0xfd, 0x29, 0x52, 0x1f,
0x64, 0xb0, 0xcb, 0x7c, 0x07, 0xd3, 0xa8, 0xe5, 0x9e, 0x4a, 0x31, 0xec, 0x97, 0x43, 0x38, 0x75, 0x0e, 0xda, 0xa1, 0x16, 0x6d, 0xb9, 0xc2, 0x8f, 0xf4,
0x20, 0x5b, 0x6a, 0x11, 0xc5, 0xbe, 0xf3, 0x88, 0x5c, 0x27, 0x90, 0xeb, 0x3f, 0x44, 0x09, 0x72, 0xa6, 0xdd, 0xef, 0x94, 0x40, 0x3b, 0x76, 0x0d, 0xd9,
0xa2, 0x15, 0x6e, 0xba, 0xc1, 0x8c, 0xf7, 0x23, 0x58, 0x69, 0x12, 0xc6, 0xbd, 0xf0, 0x8b, 0x5f, 0x24, 0x93, 0xe8, 0x3c, 0x47, 0x0a, 0x71, 0xa5, 0xde,
0x03, 0x78, 0xac, 0xd7, 0x9a, 0xe1, 0x35, 0x4e, 0xf9, 0x82, 0x56, 0x2d, 0x60, 0x1b, 0xcf, 0xb4, 0x85, 0xfe, 0x2a, 0x51, 0x1c, 0x67, 0xb3, 0xc8, 0x7f,
0x04, 0xd0, 0xab, 0xe6, 0x9d, 0x49, 0x32, 0x8d, 0xf6, 0x22, 0x59, 0x14, 0x6f, 0xbb, 0xc0, 0x77, 0x0c, 0xd8, 0xa3, 0xee, 0x95, 0x41, 0x3a, 0x0b, 0x70,
0xa4, 0xdf, 0x92, 0xe9, 0x3d, 0x46, 0xf1, 0x8a, 0x5e, 0x25, 0x68, 0x13, 0xc7, 0xbc, 0x61, 0x1a, 0xce, 0xb5, 0xf8, 0x83, 0x57, 0x2c, 0x9b, 0xe0, 0x34,
0x4f, 0x02, 0x79, 0xad, 0xd6, 0xe7, 0x9c, 0x48, 0x33, 0x7e, 0x05, 0xd1, 0xaa, 0x1d, 0x66, 0xb2, 0xc9, 0x84, 0xff, 0x2b, 0x50, 0x62, 0x19, 0xcd, 0xb6,
0xfb, 0x80, 0x54, 0x2f, 0x98, 0xe3, 0x37, 0x4c, 0x01, 0x7a, 0xae, 0xd5, 0xe4, 0x9f, 0x4b, 0x30, 0x7d, 0x06, 0xd2, 0xa9, 0x1e, 0x65, 0xb1, 0xca, 0x87,
0xfc, 0x28, 0x53, 0x8e, 0xf5, 0x21, 0x5a, 0x17, 0x6c, 0xb8, 0xc3, 0x74, 0x0f, 0xdb, 0xa0, 0xed, 0x96, 0x42, 0x39, 0x08, 0x73, 0xa7, 0xdc, 0x91, 0xea,
0x3e, 0x45, 0xf2, 0x89, 0x5d, 0x26, 0x6b, 0x10, 0xc4, 0xbf
const uint8_t toDB[] = {
0x00, 0x7b, 0xaf, 0xd4, 0x99, 0xe2, 0x36, 0x4d, 0xfa, 0x81, 0x55, 0x2e, 0x63, 0x18, 0xcc, 0xb7, 0x86, 0xfd, 0x29, 0x52, 0x1f,
0x64, 0xb0, 0xcb, 0x7c, 0x07, 0xd3, 0xa8, 0xe5, 0x9e, 0x4a, 0x31, 0xec, 0x97, 0x43, 0x38, 0x75, 0x0e, 0xda, 0xa1, 0x16, 0x6d, 0xb9, 0xc2, 0x8f, 0xf4,
0x20, 0x5b, 0x6a, 0x11, 0xc5, 0xbe, 0xf3, 0x88, 0x5c, 0x27, 0x90, 0xeb, 0x3f, 0x44, 0x09, 0x72, 0xa6, 0xdd, 0xef, 0x94, 0x40, 0x3b, 0x76, 0x0d, 0xd9,
0xa2, 0x15, 0x6e, 0xba, 0xc1, 0x8c, 0xf7, 0x23, 0x58, 0x69, 0x12, 0xc6, 0xbd, 0xf0, 0x8b, 0x5f, 0x24, 0x93, 0xe8, 0x3c, 0x47, 0x0a, 0x71, 0xa5, 0xde,
0x03, 0x78, 0xac, 0xd7, 0x9a, 0xe1, 0x35, 0x4e, 0xf9, 0x82, 0x56, 0x2d, 0x60, 0x1b, 0xcf, 0xb4, 0x85, 0xfe, 0x2a, 0x51, 0x1c, 0x67, 0xb3, 0xc8, 0x7f,
0x04, 0xd0, 0xab, 0xe6, 0x9d, 0x49, 0x32, 0x8d, 0xf6, 0x22, 0x59, 0x14, 0x6f, 0xbb, 0xc0, 0x77, 0x0c, 0xd8, 0xa3, 0xee, 0x95, 0x41, 0x3a, 0x0b, 0x70,
0xa4, 0xdf, 0x92, 0xe9, 0x3d, 0x46, 0xf1, 0x8a, 0x5e, 0x25, 0x68, 0x13, 0xc7, 0xbc, 0x61, 0x1a, 0xce, 0xb5, 0xf8, 0x83, 0x57, 0x2c, 0x9b, 0xe0, 0x34,
0x4f, 0x02, 0x79, 0xad, 0xd6, 0xe7, 0x9c, 0x48, 0x33, 0x7e, 0x05, 0xd1, 0xaa, 0x1d, 0x66, 0xb2, 0xc9, 0x84, 0xff, 0x2b, 0x50, 0x62, 0x19, 0xcd, 0xb6,
0xfb, 0x80, 0x54, 0x2f, 0x98, 0xe3, 0x37, 0x4c, 0x01, 0x7a, 0xae, 0xd5, 0xe4, 0x9f, 0x4b, 0x30, 0x7d, 0x06, 0xd2, 0xa9, 0x1e, 0x65, 0xb1, 0xca, 0x87,
0xfc, 0x28, 0x53, 0x8e, 0xf5, 0x21, 0x5a, 0x17, 0x6c, 0xb8, 0xc3, 0x74, 0x0f, 0xdb, 0xa0, 0xed, 0x96, 0x42, 0x39, 0x08, 0x73, 0xa7, 0xdc, 0x91, 0xea,
0x3e, 0x45, 0xf2, 0x89, 0x5d, 0x26, 0x6b, 0x10, 0xc4, 0xbf
};
const uint8_t fromDB[] = {
0x00, 0xcc, 0xac, 0x60, 0x79, 0xb5, 0xd5, 0x19, 0xf0, 0x3c, 0x5c, 0x90, 0x89, 0x45, 0x25, 0xe9, 0xfd, 0x31, 0x51, 0x9d,
0x84, 0x48, 0x28, 0xe4, 0x0d, 0xc1, 0xa1, 0x6d, 0x74, 0xb8, 0xd8, 0x14, 0x2e, 0xe2, 0x82, 0x4e, 0x57, 0x9b, 0xfb, 0x37, 0xde, 0x12, 0x72, 0xbe, 0xa7,
0x6b, 0x0b, 0xc7, 0xd3, 0x1f, 0x7f, 0xb3, 0xaa, 0x66, 0x06, 0xca, 0x23, 0xef, 0x8f, 0x43, 0x5a, 0x96, 0xf6, 0x3a, 0x42, 0x8e, 0xee, 0x22, 0x3b, 0xf7,
0x97, 0x5b, 0xb2, 0x7e, 0x1e, 0xd2, 0xcb, 0x07, 0x67, 0xab, 0xbf, 0x73, 0x13, 0xdf, 0xc6, 0x0a, 0x6a, 0xa6, 0x4f, 0x83, 0xe3, 0x2f, 0x36, 0xfa, 0x9a,
0x56, 0x6c, 0xa0, 0xc0, 0x0c, 0x15, 0xd9, 0xb9, 0x75, 0x9c, 0x50, 0x30, 0xfc, 0xe5, 0x29, 0x49, 0x85, 0x91, 0x5d, 0x3d, 0xf1, 0xe8, 0x24, 0x44, 0x88,
0x61, 0xad, 0xcd, 0x01, 0x18, 0xd4, 0xb4, 0x78, 0xc5, 0x09, 0x69, 0xa5, 0xbc, 0x70, 0x10, 0xdc, 0x35, 0xf9, 0x99, 0x55, 0x4c, 0x80, 0xe0, 0x2c, 0x38,
0xf4, 0x94, 0x58, 0x41, 0x8d, 0xed, 0x21, 0xc8, 0x04, 0x64, 0xa8, 0xb1, 0x7d, 0x1d, 0xd1, 0xeb, 0x27, 0x47, 0x8b, 0x92, 0x5e, 0x3e, 0xf2, 0x1b, 0xd7,
0xb7, 0x7b, 0x62, 0xae, 0xce, 0x02, 0x16, 0xda, 0xba, 0x76, 0x6f, 0xa3, 0xc3, 0x0f, 0xe6, 0x2a, 0x4a, 0x86, 0x9f, 0x53, 0x33, 0xff, 0x87, 0x4b, 0x2b,
0xe7, 0xfe, 0x32, 0x52, 0x9e, 0x77, 0xbb, 0xdb, 0x17, 0x0e, 0xc2, 0xa2, 0x6e, 0x7a, 0xb6, 0xd6, 0x1a, 0x03, 0xcf, 0xaf, 0x63, 0x8a, 0x46, 0x26, 0xea,
0xf3, 0x3f, 0x5f, 0x93, 0xa9, 0x65, 0x05, 0xc9, 0xd0, 0x1c, 0x7c, 0xb0, 0x59, 0x95, 0xf5, 0x39, 0x20, 0xec, 0x8c, 0x40, 0x54, 0x98, 0xf8, 0x34, 0x2d,
0xe1, 0x81, 0x4d, 0xa4, 0x68, 0x08, 0xc4, 0xdd, 0x11, 0x71, 0xbd
0x84, 0x48, 0x28, 0xe4, 0x0d, 0xc1, 0xa1, 0x6d, 0x74, 0xb8, 0xd8, 0x14, 0x2e, 0xe2, 0x82, 0x4e, 0x57, 0x9b, 0xfb, 0x37, 0xde, 0x12, 0x72, 0xbe, 0xa7,
0x6b, 0x0b, 0xc7, 0xd3, 0x1f, 0x7f, 0xb3, 0xaa, 0x66, 0x06, 0xca, 0x23, 0xef, 0x8f, 0x43, 0x5a, 0x96, 0xf6, 0x3a, 0x42, 0x8e, 0xee, 0x22, 0x3b, 0xf7,
0x97, 0x5b, 0xb2, 0x7e, 0x1e, 0xd2, 0xcb, 0x07, 0x67, 0xab, 0xbf, 0x73, 0x13, 0xdf, 0xc6, 0x0a, 0x6a, 0xa6, 0x4f, 0x83, 0xe3, 0x2f, 0x36, 0xfa, 0x9a,
0x56, 0x6c, 0xa0, 0xc0, 0x0c, 0x15, 0xd9, 0xb9, 0x75, 0x9c, 0x50, 0x30, 0xfc, 0xe5, 0x29, 0x49, 0x85, 0x91, 0x5d, 0x3d, 0xf1, 0xe8, 0x24, 0x44, 0x88,
0x61, 0xad, 0xcd, 0x01, 0x18, 0xd4, 0xb4, 0x78, 0xc5, 0x09, 0x69, 0xa5, 0xbc, 0x70, 0x10, 0xdc, 0x35, 0xf9, 0x99, 0x55, 0x4c, 0x80, 0xe0, 0x2c, 0x38,
0xf4, 0x94, 0x58, 0x41, 0x8d, 0xed, 0x21, 0xc8, 0x04, 0x64, 0xa8, 0xb1, 0x7d, 0x1d, 0xd1, 0xeb, 0x27, 0x47, 0x8b, 0x92, 0x5e, 0x3e, 0xf2, 0x1b, 0xd7,
0xb7, 0x7b, 0x62, 0xae, 0xce, 0x02, 0x16, 0xda, 0xba, 0x76, 0x6f, 0xa3, 0xc3, 0x0f, 0xe6, 0x2a, 0x4a, 0x86, 0x9f, 0x53, 0x33, 0xff, 0x87, 0x4b, 0x2b,
0xe7, 0xfe, 0x32, 0x52, 0x9e, 0x77, 0xbb, 0xdb, 0x17, 0x0e, 0xc2, 0xa2, 0x6e, 0x7a, 0xb6, 0xd6, 0x1a, 0x03, 0xcf, 0xaf, 0x63, 0x8a, 0x46, 0x26, 0xea,
0xf3, 0x3f, 0x5f, 0x93, 0xa9, 0x65, 0x05, 0xc9, 0xd0, 0x1c, 0x7c, 0xb0, 0x59, 0x95, 0xf5, 0x39, 0x20, 0xec, 0x8c, 0x40, 0x54, 0x98, 0xf8, 0x34, 0x2d,
0xe1, 0x81, 0x4d, 0xa4, 0x68, 0x08, 0xc4, 0xdd, 0x11, 0x71, 0xbd
};
const uint8_t randVals[] = {
@ -69,7 +68,7 @@ namespace dsp {
for (int i = 0; i < 5; i++) { memset(outBuffers[i], 0, 255); }
rs = correct_reed_solomon_create(correct_rs_primitive_polynomial_ccsds, 120, 11, 16);
if (rs == NULL) { printf("Error creating the reed solomon decoder\n"); }
generic_block<FalconRS>::registerInput(_in);
generic_block<FalconRS>::registerOutput(&out);
generic_block<FalconRS>::_block_init = true;
@ -92,29 +91,44 @@ namespace dsp {
uint8_t* data = _in->readBuf + 4;
// Deinterleave
for (int i = 0; i < 255*5; i++) {
buffers[i%5][i/5] = fromDB[data[i]];
for (int i = 0; i < 255 * 5; i++) {
buffers[i % 5][i / 5] = fromDB[data[i]];
}
// Reed the solomon :weary:
int result = 0;
result = correct_reed_solomon_decode(rs, buffers[0], 255, outBuffers[0]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[1], 255, outBuffers[1]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[2], 255, outBuffers[2]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[3], 255, outBuffers[3]);
if (result == -1) { _in->flush(); return count; }
if (result == -1) {
_in->flush();
return count;
}
result = correct_reed_solomon_decode(rs, buffers[4], 255, outBuffers[4]);
if (result == -1) { _in->flush(); return count; }
// Reinterleave
for (int i = 0; i < 255*5; i++) {
out.writeBuf[i] = toDB[outBuffers[i%5][i/5]] ^ randVals[i % 255];
if (result == -1) {
_in->flush();
return count;
}
out.swap(255*5);
// Reinterleave
for (int i = 0; i < 255 * 5; i++) {
out.writeBuf[i] = toDB[outBuffers[i % 5][i / 5]] ^ randVals[i % 255];
}
out.swap(255 * 5);
_in->flush();
return count;
@ -127,8 +141,7 @@ namespace dsp {
uint8_t buffers[5][255];
uint8_t outBuffers[5][255];
correct_reed_solomon* rs;
stream<uint8_t>* _in;
stream<uint8_t>* _in;
};
}

View File

@ -16,7 +16,7 @@ namespace dsp {
void init(stream<uint8_t>* in) {
_in = in;
generic_block<FalconPacketSync>::registerInput(_in);
generic_block<FalconPacketSync>::registerOutput(&out);
generic_block<FalconPacketSync>::_block_init = true;
@ -63,7 +63,7 @@ namespace dsp {
else if (header.packet == 2047) {
printf("Wow, all data\n");
_in->flush();
return count;
return count;
}
// Finish reading the last package and send it
@ -91,9 +91,8 @@ namespace dsp {
packetRead = -1;
break;
}
uint64_t pktId = ((uint64_t)data[i + 2] << 56) | ((uint64_t)data[i + 3] << 48) | ((uint64_t)data[i + 4] << 40) | ((uint64_t)data[i + 5] << 32)
| ((uint64_t)data[i + 6] << 24) | ((uint64_t)data[i + 7] << 16) | ((uint64_t)data[i + 8] << 8) | data[i + 9];
uint64_t pktId = ((uint64_t)data[i + 2] << 56) | ((uint64_t)data[i + 3] << 48) | ((uint64_t)data[i + 4] << 40) | ((uint64_t)data[i + 5] << 32) | ((uint64_t)data[i + 6] << 24) | ((uint64_t)data[i + 7] << 16) | ((uint64_t)data[i + 8] << 8) | data[i + 9];
// If the packet doesn't fit the frame, save and go to next frame
if (dataLen - i < length) {
@ -106,7 +105,6 @@ namespace dsp {
memcpy(out.writeBuf, &data[i], length);
out.swap(length);
i += length;
}
_in->flush();
@ -121,8 +119,7 @@ namespace dsp {
int packetRead = -1;
uint8_t packet[0x4008];
stream<uint8_t>* _in;
stream<uint8_t>* _in;
};
}

View File

@ -66,12 +66,12 @@ namespace dsp {
if constexpr (std::is_same_v<T, float>) {
for (int i = 0; i < count; i++) {
volk_32f_x2_dot_prod_32f((float*)&out.writeBuf[i], (float*)&buffer[i+1], taps, tapCount);
volk_32f_x2_dot_prod_32f((float*)&out.writeBuf[i], (float*)&buffer[i + 1], taps, tapCount);
}
}
if constexpr (std::is_same_v<T, complex_t>) {
for (int i = 0; i < count; i++) {
volk_32fc_32f_dot_prod_32fc((lv_32fc_t*)&out.writeBuf[i], (lv_32fc_t*)&buffer[i+1], taps, tapCount);
volk_32fc_32f_dot_prod_32fc((lv_32fc_t*)&out.writeBuf[i], (lv_32fc_t*)&buffer[i + 1], taps, tapCount);
}
}
@ -95,7 +95,6 @@ namespace dsp {
T* buffer;
int tapCount;
float* taps;
};
class ComplexFIR : public generic_block<ComplexFIR> {
@ -157,7 +156,7 @@ namespace dsp {
_in->flush();
for (int i = 0; i < count; i++) {
volk_32fc_x2_dot_prod_32fc((lv_32fc_t*)&out.writeBuf[i], (lv_32fc_t*)&buffer[i+1], (lv_32fc_t*)taps, tapCount);
volk_32fc_x2_dot_prod_32fc((lv_32fc_t*)&out.writeBuf[i], (lv_32fc_t*)&buffer[i + 1], (lv_32fc_t*)taps, tapCount);
}
if (!out.swap(count)) { return -1; }
@ -180,7 +179,6 @@ namespace dsp {
complex_t* buffer;
int tapCount;
complex_t* taps;
};
class BFMDeemp : public generic_block<BFMDeemp> {
@ -241,8 +239,8 @@ namespace dsp {
if (isnan(lastOutR)) {
lastOutR = 0.0f;
}
out.writeBuf[0].l = (alpha * _in->readBuf[0].l) + ((1-alpha) * lastOutL);
out.writeBuf[0].r = (alpha * _in->readBuf[0].r) + ((1-alpha) * lastOutR);
out.writeBuf[0].l = (alpha * _in->readBuf[0].l) + ((1 - alpha) * lastOutL);
out.writeBuf[0].r = (alpha * _in->readBuf[0].r) + ((1 - alpha) * lastOutR);
for (int i = 1; i < count; i++) {
out.writeBuf[i].l = (alpha * _in->readBuf[i].l) + ((1 - alpha) * out.writeBuf[i - 1].l);
out.writeBuf[i].r = (alpha * _in->readBuf[i].r) + ((1 - alpha) * out.writeBuf[i - 1].r);
@ -267,6 +265,5 @@ namespace dsp {
float _tau;
float _sampleRate;
stream<stereo_t>* _in;
};
}

View File

@ -82,7 +82,6 @@ namespace dsp {
private:
stream<T>* _a;
stream<T>* _b;
};
template <class T>
@ -163,7 +162,6 @@ namespace dsp {
private:
stream<T>* _a;
stream<T>* _b;
};
template <class T>
@ -244,6 +242,5 @@ namespace dsp {
private:
stream<T>* _a;
stream<T>* _b;
};
}

View File

@ -46,14 +46,14 @@ namespace dsp {
float _lvlL = 10.0f * logf(maxL);
float _lvlR = 10.0f * logf(maxR);
// Update max values
{
std::lock_guard<std::mutex> lck(lvlMtx);
if (_lvlL > lvlL) { lvlL = _lvlL; }
if (_lvlR > lvlR) { lvlR = _lvlR; }
}
return count;
}
@ -77,6 +77,5 @@ namespace dsp {
float lvlR = -90.0f;
stream<stereo_t>* _in;
std::mutex lvlMtx;
};
}

View File

@ -61,7 +61,6 @@ namespace dsp {
private:
stream<uint8_t>* _in;
};
}
}

View File

@ -72,7 +72,6 @@ namespace dsp {
private:
stream<uint8_t>* _in;
};
}
}

View File

@ -9,12 +9,12 @@ namespace dsp {
}
const uint8_t HRPTSyncWord[] = {
1,0,1,0,0,0,0,1,0,0,
0,1,0,1,1,0,1,1,1,1,
1,1,0,1,0,1,1,1,0,0,
0,1,1,0,0,1,1,1,0,1,
1,0,0,0,0,0,1,1,1,1,
0,0,1,0,0,1,0,1,0,1
1, 0, 1, 0, 0, 0, 0, 1, 0, 0,
0, 1, 0, 1, 1, 0, 1, 1, 1, 1,
1, 1, 0, 1, 0, 1, 1, 1, 0, 0,
0, 1, 1, 0, 0, 1, 1, 1, 0, 1,
1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 1, 0, 0, 1, 0, 1, 0, 1
};
class HRPTDemux : public generic_block<HRPTDemux> {
@ -105,7 +105,6 @@ namespace dsp {
private:
stream<uint8_t>* _in;
};
}
}

View File

@ -132,7 +132,6 @@ namespace dsp {
private:
stream<uint8_t>* _in;
};
inline uint16_t HIRSSignedToUnsigned(uint16_t n) {
@ -236,7 +235,6 @@ namespace dsp {
stream<uint8_t>* _in;
int lastElement = 0;
bool newImageData = false;
};
}
}

View File

@ -3,7 +3,7 @@
#include <dsp/utils/window_functions.h>
#include <fftw3.h>
#define NR_TAP_COUNT 64
#define NR_TAP_COUNT 64
namespace dsp {
class FMIFNoiseReduction : public generic_block<FMIFNoiseReduction> {
@ -30,22 +30,22 @@ namespace dsp {
_in = in;
_tapCount = tapCount;
delay = (complex_t*)fftwf_malloc(sizeof(complex_t)*STREAM_BUFFER_SIZE);
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
fft_window = (float*)fftwf_malloc(sizeof(float)*_tapCount);
amp_buf = (float*)fftwf_malloc(sizeof(float)*_tapCount);
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
fft_cin = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
fft_fcout = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
delay = (complex_t*)fftwf_malloc(sizeof(complex_t) * STREAM_BUFFER_SIZE);
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
fft_window = (float*)fftwf_malloc(sizeof(float) * _tapCount);
amp_buf = (float*)fftwf_malloc(sizeof(float) * _tapCount);
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
fft_cin = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
fft_fcout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
delay_start = &delay[_tapCount];
memset(delay, 0, sizeof(complex_t)*STREAM_BUFFER_SIZE);
memset(fft_in, 0, sizeof(complex_t)*_tapCount);
memset(amp_buf, 0, sizeof(float)*_tapCount);
memset(fft_cout, 0, sizeof(complex_t)*_tapCount);
memset(fft_cin, 0, sizeof(complex_t)*_tapCount);
memset(fft_fcout, 0, sizeof(complex_t)*_tapCount);
memset(delay, 0, sizeof(complex_t) * STREAM_BUFFER_SIZE);
memset(fft_in, 0, sizeof(complex_t) * _tapCount);
memset(amp_buf, 0, sizeof(float) * _tapCount);
memset(fft_cout, 0, sizeof(complex_t) * _tapCount);
memset(fft_cin, 0, sizeof(complex_t) * _tapCount);
memset(fft_fcout, 0, sizeof(complex_t) * _tapCount);
for (int i = 0; i < _tapCount; i++) {
fft_window[i] = window_function::blackman(i, _tapCount - 1);
}
@ -86,22 +86,22 @@ namespace dsp {
fftwf_free(fft_cin);
fftwf_free(fft_fcout);
delay = (complex_t*)fftwf_malloc(sizeof(complex_t)*STREAM_BUFFER_SIZE);
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
fft_window = (float*)fftwf_malloc(sizeof(float)*_tapCount);
amp_buf = (float*)fftwf_malloc(sizeof(float)*_tapCount);
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
fft_cin = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
fft_fcout = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
delay = (complex_t*)fftwf_malloc(sizeof(complex_t) * STREAM_BUFFER_SIZE);
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
fft_window = (float*)fftwf_malloc(sizeof(float) * _tapCount);
amp_buf = (float*)fftwf_malloc(sizeof(float) * _tapCount);
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
fft_cin = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
fft_fcout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
delay_start = &delay[_tapCount];
memset(delay, 0, sizeof(complex_t)*STREAM_BUFFER_SIZE);
memset(fft_in, 0, sizeof(complex_t)*_tapCount);
memset(amp_buf, 0, sizeof(float)*_tapCount);
memset(fft_cout, 0, sizeof(complex_t)*_tapCount);
memset(fft_cin, 0, sizeof(complex_t)*_tapCount);
memset(fft_fcout, 0, sizeof(complex_t)*_tapCount);
memset(delay, 0, sizeof(complex_t) * STREAM_BUFFER_SIZE);
memset(fft_in, 0, sizeof(complex_t) * _tapCount);
memset(amp_buf, 0, sizeof(float) * _tapCount);
memset(fft_cout, 0, sizeof(complex_t) * _tapCount);
memset(fft_cin, 0, sizeof(complex_t) * _tapCount);
memset(fft_fcout, 0, sizeof(complex_t) * _tapCount);
for (int i = 0; i < _tapCount; i++) {
fft_window[i] = window_function::blackman(i, _tapCount - 1);
}
@ -154,13 +154,13 @@ namespace dsp {
// Do reverse FFT and get first element
fftwf_execute(backwardPlan);
out.writeBuf[i] = fft_fcout[_tapCount/2];
out.writeBuf[i] = fft_fcout[_tapCount / 2];
// Reset the input buffer
fft_cin[idx] = {0, 0};
fft_cin[idx] = { 0, 0 };
}
volk_32f_s32f_multiply_32f((float*)out.writeBuf, (float*)out.writeBuf, 1.0f/(float)_tapCount, count * 2);
volk_32f_s32f_multiply_32f((float*)out.writeBuf, (float*)out.writeBuf, 1.0f / (float)_tapCount, count * 2);
// Copy last values to delay
memmove(delay, &delay[count], _tapCount * sizeof(complex_t));
@ -169,7 +169,7 @@ namespace dsp {
if (!out.swap(count)) { return -1; }
return count;
}
bool bypass = true;
stream<complex_t> out;
@ -189,7 +189,6 @@ namespace dsp {
complex_t* fft_fcout;
int _tapCount;
};
class FFTNoiseReduction : public generic_block<FFTNoiseReduction> {
@ -214,20 +213,20 @@ namespace dsp {
void init(stream<float>* in) {
_in = in;
delay = (float*)fftwf_malloc(sizeof(float)*STREAM_BUFFER_SIZE);
fft_in = (float*)fftwf_malloc(sizeof(float)*NR_TAP_COUNT);
fft_window = (float*)fftwf_malloc(sizeof(float)*NR_TAP_COUNT);
amp_buf = (float*)fftwf_malloc(sizeof(float)*NR_TAP_COUNT);
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t)*NR_TAP_COUNT);
fft_fout = (float*)fftwf_malloc(sizeof(float)*NR_TAP_COUNT);
delay = (float*)fftwf_malloc(sizeof(float) * STREAM_BUFFER_SIZE);
fft_in = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
fft_window = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
amp_buf = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t) * NR_TAP_COUNT);
fft_fout = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
delay_start = &delay[NR_TAP_COUNT];
memset(delay, 0, sizeof(float)*STREAM_BUFFER_SIZE);
memset(fft_in, 0, sizeof(float)*NR_TAP_COUNT);
memset(amp_buf, 0, sizeof(float)*NR_TAP_COUNT);
memset(fft_cout, 0, sizeof(complex_t)*NR_TAP_COUNT);
memset(fft_fout, 0, sizeof(float)*NR_TAP_COUNT);
memset(delay, 0, sizeof(float) * STREAM_BUFFER_SIZE);
memset(fft_in, 0, sizeof(float) * NR_TAP_COUNT);
memset(amp_buf, 0, sizeof(float) * NR_TAP_COUNT);
memset(fft_cout, 0, sizeof(complex_t) * NR_TAP_COUNT);
memset(fft_fout, 0, sizeof(float) * NR_TAP_COUNT);
for (int i = 0; i < NR_TAP_COUNT; i++) {
fft_window[i] = window_function::blackman(i, NR_TAP_COUNT - 1);
}
@ -274,19 +273,19 @@ namespace dsp {
fftwf_execute(forwardPlan);
// Process bins here
volk_32fc_magnitude_32f(amp_buf, (lv_32fc_t*)fft_cout, NR_TAP_COUNT/2);
for (int j = 1; j < NR_TAP_COUNT/2; j++) {
volk_32fc_magnitude_32f(amp_buf, (lv_32fc_t*)fft_cout, NR_TAP_COUNT / 2);
for (int j = 1; j < NR_TAP_COUNT / 2; j++) {
if (log10f(amp_buf[0]) < level) {
fft_cout[j] = {0, 0};
fft_cout[j] = { 0, 0 };
}
}
// Do reverse FFT and get first element
fftwf_execute(backwardPlan);
out.writeBuf[i] = fft_fout[NR_TAP_COUNT/2];
out.writeBuf[i] = fft_fout[NR_TAP_COUNT / 2];
}
volk_32f_s32f_multiply_32f(out.writeBuf, out.writeBuf, 1.0f/(float)NR_TAP_COUNT, count);
volk_32f_s32f_multiply_32f(out.writeBuf, out.writeBuf, 1.0f / (float)NR_TAP_COUNT, count);
// Copy last values to delay
memmove(delay, &delay[count], NR_TAP_COUNT * sizeof(float));
@ -295,7 +294,7 @@ namespace dsp {
if (!out.swap(count)) { return -1; }
return count;
}
bool bypass = true;
stream<float> out;
@ -312,7 +311,6 @@ namespace dsp {
float* delay_start;
complex_t* fft_cout;
float* fft_fout;
};
class NoiseBlanker : public generic_block<NoiseBlanker> {
@ -329,9 +327,10 @@ namespace dsp {
void init(stream<complex_t>* in, float level) {
_in = in;
_level = powf(10.0f, level / 10.0f);;
_level = powf(10.0f, level / 10.0f);
;
ampBuf = (float*)volk_malloc(STREAM_BUFFER_SIZE*sizeof(float), volk_get_alignment());
ampBuf = (float*)volk_malloc(STREAM_BUFFER_SIZE * sizeof(float), volk_get_alignment());
generic_block<NoiseBlanker>::registerInput(_in);
generic_block<NoiseBlanker>::registerOutput(&out);
@ -377,9 +376,8 @@ namespace dsp {
float* ampBuf;
float _level;
stream<complex_t>* _in;
stream<complex_t>* _in;
};
class NotchFilter : public generic_block<NotchFilter> {
@ -395,7 +393,7 @@ namespace dsp {
_sampleRate = sampleRate;
phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
phaseDeltaConj = {phaseDelta.real(), -phaseDelta.imag()};
phaseDeltaConj = { phaseDelta.real(), -phaseDelta.imag() };
generic_block<NotchFilter>::registerInput(_in);
generic_block<NotchFilter>::registerOutput(&out);
@ -419,13 +417,13 @@ namespace dsp {
void setOffset(float offset) {
_offset = offset;
phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
phaseDeltaConj = {phaseDelta.real(), -phaseDelta.imag()};
phaseDeltaConj = { phaseDelta.real(), -phaseDelta.imag() };
}
void setSampleRate(float sampleRate) {
_sampleRate = sampleRate;
phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
phaseDeltaConj = {phaseDelta.real(), -phaseDelta.imag()};
phaseDeltaConj = { phaseDelta.real(), -phaseDelta.imag() };
}
int run() {
@ -452,14 +450,13 @@ namespace dsp {
private:
stream<complex_t>* _in;
complex_t offset = {0, 0};
lv_32fc_t inPhase = {1, 0};
lv_32fc_t outPhase = {4, 0};
complex_t offset = { 0, 0 };
lv_32fc_t inPhase = { 1, 0 };
lv_32fc_t outPhase = { 4, 0 };
lv_32fc_t phaseDelta;
lv_32fc_t phaseDeltaConj;
float _offset;
float _sampleRate;
float correctionRate;
};
}

View File

@ -7,7 +7,7 @@
namespace dsp {
template <int ORDER>
class CostasLoop: public generic_block<CostasLoop<ORDER>> {
class CostasLoop : public generic_block<CostasLoop<ORDER>> {
public:
CostasLoop() {}
@ -59,8 +59,8 @@ namespace dsp {
for (int i = 0; i < count; i++) {
// Mix the VFO with the input to create the output value
outVal.re = (lastVCO.re*_in->readBuf[i].re) - (lastVCO.im*_in->readBuf[i].im);
outVal.im = (lastVCO.im*_in->readBuf[i].re) + (lastVCO.re*_in->readBuf[i].im);
outVal.re = (lastVCO.re * _in->readBuf[i].re) - (lastVCO.im * _in->readBuf[i].im);
outVal.im = (lastVCO.im * _in->readBuf[i].re) + (lastVCO.re * _in->readBuf[i].im);
out.writeBuf[i] = outVal;
// Calculate the phase error estimation
@ -75,20 +75,25 @@ namespace dsp {
const float K = (sqrtf(2.0) - 1);
if (fabsf(outVal.re) >= fabsf(outVal.im)) {
error = ((outVal.re > 0.0f ? 1.0f : -1.0f) * outVal.im -
(outVal.im > 0.0f ? 1.0f : -1.0f) * outVal.re * K);
} else {
(outVal.im > 0.0f ? 1.0f : -1.0f) * outVal.re * K);
}
else {
error = ((outVal.re > 0.0f ? 1.0f : -1.0f) * outVal.im * K -
(outVal.im > 0.0f ? 1.0f : -1.0f) * outVal.re);
(outVal.im > 0.0f ? 1.0f : -1.0f) * outVal.re);
}
}
if (error > 1.0f) { error = 1.0f; }
else if (error < -1.0f) { error = -1.0f; }
else if (error < -1.0f) {
error = -1.0f;
}
// Integrate frequency and clamp it
vcoFrequency += _beta * error;
if (vcoFrequency > 1.0f) { vcoFrequency = 1.0f; }
else if (vcoFrequency < -1.0f) { vcoFrequency = -1.0f; }
else if (vcoFrequency < -1.0f) {
vcoFrequency = -1.0f;
}
// Calculate new phase and wrap it
vcoPhase += vcoFrequency + (_alpha * error);
@ -98,9 +103,8 @@ namespace dsp {
// Calculate output
lastVCO.re = cosf(-vcoPhase);
lastVCO.im = sinf(-vcoPhase);
}
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
@ -112,17 +116,16 @@ namespace dsp {
float _loopBandwidth = 1.0f;
float _alpha; // Integral coefficient
float _beta; // Proportional coefficient
float _beta; // Proportional coefficient
float vcoFrequency = 0.0f;
float vcoPhase = 0.0f;
complex_t lastVCO;
stream<complex_t>* _in;
};
template <class T>
class CarrierTrackingPLL: public generic_block<CarrierTrackingPLL<T>> {
class CarrierTrackingPLL : public generic_block<CarrierTrackingPLL<T>> {
public:
CarrierTrackingPLL() {}
@ -174,8 +177,8 @@ namespace dsp {
for (int i = 0; i < count; i++) {
// Mix the VFO with the input to create the output value
outVal.re = (lastVCO.re*_in->readBuf[i].re) - ((-lastVCO.im)*_in->readBuf[i].im);
outVal.im = ((-lastVCO.im)*_in->readBuf[i].re) + (lastVCO.re*_in->readBuf[i].im);
outVal.re = (lastVCO.re * _in->readBuf[i].re) - ((-lastVCO.im) * _in->readBuf[i].im);
outVal.im = ((-lastVCO.im) * _in->readBuf[i].re) + (lastVCO.re * _in->readBuf[i].im);
if constexpr (std::is_same_v<T, float>) {
out.writeBuf[i] = outVal.fastPhase();
@ -187,16 +190,20 @@ namespace dsp {
// Calculate the phase error estimation
// TODO: Figure out why fastPhase doesn't work
error = _in->readBuf[i].phase() - vcoPhase;
if (error > 3.1415926535f) { error -= 2.0f * 3.1415926535f; }
else if (error <= -3.1415926535f) { error += 2.0f * 3.1415926535f; }
if (error > 3.1415926535f) { error -= 2.0f * 3.1415926535f; }
else if (error <= -3.1415926535f) {
error += 2.0f * 3.1415926535f;
}
// if (error > 1.0f) { error = 1.0f; }
// else if (error < -1.0f) { error = -1.0f; }
// Integrate frequency and clamp it
vcoFrequency += _beta * error;
if (vcoFrequency > 1.0f) { vcoFrequency = 1.0f; }
else if (vcoFrequency < -1.0f) { vcoFrequency = -1.0f; }
else if (vcoFrequency < -1.0f) {
vcoFrequency = -1.0f;
}
// Calculate new phase and wrap it
vcoPhase += vcoFrequency + (_alpha * error);
@ -206,9 +213,8 @@ namespace dsp {
// Calculate output
lastVCO.re = cosf(vcoPhase);
lastVCO.im = sinf(vcoPhase);
}
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
@ -220,16 +226,15 @@ namespace dsp {
float _loopBandwidth = 1.0f;
float _alpha; // Integral coefficient
float _beta; // Proportional coefficient
float _beta; // Proportional coefficient
float vcoFrequency = 0.0f;
float vcoPhase = 0.0f;
complex_t lastVCO;
stream<complex_t>* _in;
};
class PLL: public generic_block<PLL> {
class PLL : public generic_block<PLL> {
public:
PLL() {}
@ -284,13 +289,17 @@ namespace dsp {
// Calculate the phase error estimation
// TODO: Figure out why fastPhase doesn't work
error = _in->readBuf[i].phase() - vcoPhase;
if (error > 3.1415926535f) { error -= 2.0f * 3.1415926535f; }
else if (error <= -3.1415926535f) { error += 2.0f * 3.1415926535f; }
if (error > 3.1415926535f) { error -= 2.0f * 3.1415926535f; }
else if (error <= -3.1415926535f) {
error += 2.0f * 3.1415926535f;
}
// Integrate frequency and clamp it
vcoFrequency += _beta * error;
if (vcoFrequency > 1.0f) { vcoFrequency = 1.0f; }
else if (vcoFrequency < -1.0f) { vcoFrequency = -1.0f; }
else if (vcoFrequency < -1.0f) {
vcoFrequency = -1.0f;
}
// Calculate new phase and wrap it
vcoPhase += vcoFrequency + (_alpha * error);
@ -300,9 +309,8 @@ namespace dsp {
// Calculate output
lastVCO.re = cosf(vcoPhase);
lastVCO.im = sinf(vcoPhase);
}
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
@ -314,12 +322,11 @@ namespace dsp {
float _loopBandwidth = 1.0f;
float _alpha; // Integral coefficient
float _beta; // Proportional coefficient
float _beta; // Proportional coefficient
float vcoFrequency = ((19000.0f / 250000.0f) * 2.0f * FL_M_PI);
float vcoPhase = 0.0f;
complex_t lastVCO;
stream<complex_t>* _in;
};
}

View File

@ -82,7 +82,6 @@ namespace dsp {
lv_32fc_t phaseDelta;
lv_32fc_t phase;
stream<complex_t>* _in;
};
class AGC : public generic_block<AGC> {
@ -155,7 +154,6 @@ namespace dsp {
float _CorrectedFallRate;
float _sampleRate;
stream<float>* _in;
};
class ComplexAGC : public generic_block<ComplexAGC> {
@ -223,9 +221,8 @@ namespace dsp {
float _setPoint = 1.0f;
float _maxGain = 10e4;
float _rate = 10e-4;
stream<complex_t>* _in;
stream<complex_t>* _in;
};
class DelayImag : public generic_block<DelayImag> {
@ -273,11 +270,9 @@ namespace dsp {
private:
float lastIm = 0.0f;
stream<complex_t>* _in;
};
template <class T>
class Volume : public generic_block<Volume<T>> {
public:
@ -358,7 +353,6 @@ namespace dsp {
float _volume = 1.0f;
bool _muted = false;
stream<T>* _in;
};
class Squelch : public generic_block<Squelch> {
@ -421,7 +415,7 @@ namespace dsp {
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
return count;
}
stream<complex_t> out;
@ -431,7 +425,6 @@ namespace dsp {
float* normBuffer;
float _level = -50.0f;
stream<complex_t>* _in;
};
template <class T>
@ -487,7 +480,7 @@ namespace dsp {
}
_in->flush();
return count;
}
@ -497,7 +490,6 @@ namespace dsp {
int samples = 1;
int read = 0;
stream<T>* _in;
};
class Threshold : public generic_block<Threshold> {
@ -551,7 +543,7 @@ namespace dsp {
_in->flush();
if (!out.swap(count)) { return -1; }
return count;
return count;
}
stream<uint8_t> out;
@ -561,7 +553,6 @@ namespace dsp {
float* normBuffer;
float _level = -50.0f;
stream<float>* _in;
};
class BFMPilotToStereo : public generic_block<BFMPilotToStereo> {
@ -614,6 +605,5 @@ namespace dsp {
stream<complex_t>* _in;
complex_t* buffer;
};
}

View File

@ -160,39 +160,39 @@ namespace dsp {
stream<T> out;
private:
void buildTapPhases(){
if(!taps){
void buildTapPhases() {
if (!taps) {
return;
}
if(!tapPhases.empty()){
if (!tapPhases.empty()) {
freeTapPhases();
}
int phases = _interp;
tapsPerPhase = (tapCount+phases-1)/phases; //Integer division ceiling
tapsPerPhase = (tapCount + phases - 1) / phases; //Integer division ceiling
bufStart = &buffer[tapsPerPhase];
for(int i = 0; i < phases; i++){
for (int i = 0; i < phases; i++) {
tapPhases.push_back((float*)volk_malloc(tapsPerPhase * sizeof(float), volk_get_alignment()));
}
int currentTap = 0;
for(int tap = 0; tap < tapsPerPhase; tap++) {
for (int tap = 0; tap < tapsPerPhase; tap++) {
for (int phase = 0; phase < phases; phase++) {
if(currentTap < tapCount) {
if (currentTap < tapCount) {
tapPhases[(_interp - 1) - phase][tap] = taps[currentTap++];
}
else{
else {
tapPhases[(_interp - 1) - phase][tap] = 0;
}
}
}
}
void freeTapPhases(){
for(auto & tapPhase : tapPhases){
void freeTapPhases() {
for (auto& tapPhase : tapPhases) {
volk_free(tapPhase);
}
tapPhases.clear();
@ -214,6 +214,5 @@ namespace dsp {
int tapsPerPhase;
std::vector<float*> tapPhases;
};
}

View File

@ -62,7 +62,6 @@ namespace dsp {
stream<T>* _in;
std::vector<stream<T>*> out;
};
template <class T>
@ -105,12 +104,11 @@ namespace dsp {
if (!outA.swap(count)) { return -1; }
if (!outB.swap(count)) { return -1; }
return count;
}
stream<T>* _in;
};
@ -183,7 +181,8 @@ namespace dsp {
}
void loop() {
while (run() >= 0);
while (run() >= 0)
;
}
void doStop() override {
@ -240,6 +239,5 @@ namespace dsp {
std::thread bufferWorkerThread;
std::thread workThread;
int _keep, _skip;
};
}

View File

@ -50,7 +50,6 @@ namespace dsp {
stream<T>* _in;
void (*_handler)(T* data, int count, void* ctx);
void* _ctx;
};
template <class T>
@ -99,7 +98,6 @@ namespace dsp {
}
stream<T>* _in;
};
template <class T>
@ -134,7 +132,6 @@ namespace dsp {
private:
stream<T>* _in;
};
template <class T>
@ -188,6 +185,5 @@ namespace dsp {
private:
stream<T>* _in;
std::ofstream file;
};
}

View File

@ -60,7 +60,7 @@ namespace dsp {
int run() {
volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out.writeBuf, zeroPhase, phaseDelta, &phase, _blockSize);
if(!out.swap(_blockSize)) { return -1; }
if (!out.swap(_blockSize)) { return -1; }
return _blockSize;
}
@ -73,7 +73,6 @@ namespace dsp {
lv_32fc_t phaseDelta;
lv_32fc_t phase;
lv_32fc_t* zeroPhase;
};
template <class T>
@ -111,6 +110,5 @@ namespace dsp {
private:
int (*_handler)(T* data, void* ctx);
void* _ctx;
};
}

View File

@ -66,10 +66,10 @@ namespace dsp {
_in->flush();
for (int i = 0; i < count; i++) {
volk_32fc_x2_dot_prod_32fc((lv_32fc_t*)&pilotOut.writeBuf[i], (lv_32fc_t*)&buffer[i+1], (lv_32fc_t*)taps, tapCount);
volk_32fc_x2_dot_prod_32fc((lv_32fc_t*)&pilotOut.writeBuf[i], (lv_32fc_t*)&buffer[i + 1], (lv_32fc_t*)taps, tapCount);
}
memcpy(dataOut.writeBuf, &buffer[tapCount - ((tapCount-1)/2)], count * sizeof(complex_t));
memcpy(dataOut.writeBuf, &buffer[tapCount - ((tapCount - 1) / 2)], count * sizeof(complex_t));
if (!pilotOut.swap(count) || !dataOut.swap(count)) {
bufMtx.unlock();
@ -85,7 +85,7 @@ namespace dsp {
stream<complex_t> dataOut;
stream<complex_t> pilotOut;
private:
stream<complex_t>* _in;
@ -98,10 +98,9 @@ namespace dsp {
complex_t* buffer;
int tapCount;
complex_t* taps;
};
class FMStereoDemux: public generic_block<FMStereoDemux> {
class FMStereoDemux : public generic_block<FMStereoDemux> {
public:
FMStereoDemux() {}
@ -163,18 +162,22 @@ namespace dsp {
for (int i = 0; i < count; i++) {
// Double the VCO, then mix it with the input data.
// IMPORTANT: THERE SHOULDN'T BE A NEED FOR A GAIN HERE
doubledVCO = lastVCO*lastVCO;
doubledVCO = lastVCO * lastVCO;
AminusBOut.writeBuf[i] = (_data->readBuf[i].re * doubledVCO.re) * 2.0f;
// Calculate the phase error estimation
error = _pilot->readBuf[i].phase() - vcoPhase;
if (error > 3.1415926535f) { error -= 2.0f * 3.1415926535f; }
else if (error <= -3.1415926535f) { error += 2.0f * 3.1415926535f; }
if (error > 3.1415926535f) { error -= 2.0f * 3.1415926535f; }
else if (error <= -3.1415926535f) {
error += 2.0f * 3.1415926535f;
}
// Integrate frequency and clamp it
vcoFrequency += _beta * error;
if (vcoFrequency > upperLimit) { vcoFrequency = upperLimit; }
else if (vcoFrequency < lowerLimit) { vcoFrequency = lowerLimit; }
else if (vcoFrequency < lowerLimit) {
vcoFrequency = lowerLimit;
}
// Calculate new phase and wrap it
vcoPhase += vcoFrequency + (_alpha * error);
@ -185,7 +188,7 @@ namespace dsp {
lastVCO.re = cosf(vcoPhase);
lastVCO.im = sinf(vcoPhase);
}
_data->flush();
_pilot->flush();
@ -207,7 +210,7 @@ namespace dsp {
const float lowerLimit = ((18800.0f / 250000.0f) * 2.0f * FL_M_PI);
float _alpha; // Integral coefficient
float _beta; // Proportional coefficient
float _beta; // Proportional coefficient
float vcoFrequency = expectedFreq;
float vcoPhase = 0.0f;
complex_t lastVCO;
@ -284,6 +287,5 @@ namespace dsp {
float* leftBuf;
float* rightBuf;
};
}

View File

@ -4,7 +4,7 @@
#include <volk/volk.h>
// 1MB buffer
#define STREAM_BUFFER_SIZE 1000000
#define STREAM_BUFFER_SIZE 1000000
namespace dsp {
class untyped_stream {
@ -35,7 +35,7 @@ namespace dsp {
{
// Wait to either swap or stop
std::unique_lock<std::mutex> lck(swapMtx);
swapCV.wait(lck, [this]{ return (canSwap || writerStop); });
swapCV.wait(lck, [this] { return (canSwap || writerStop); });
// If writer was stopped, abandon operation
if (writerStop) { return false; }
@ -61,7 +61,7 @@ namespace dsp {
int read() {
// Wait for data to be ready or to be stopped
std::unique_lock<std::mutex> lck(rdyMtx);
rdyCV.wait(lck, [this]{ return (dataReady || readerStop); });
rdyCV.wait(lck, [this] { return (dataReady || readerStop); });
return (readerStop ? -1 : dataSize);
}

View File

@ -5,27 +5,27 @@
namespace dsp {
struct complex_t {
complex_t operator*(const float b) {
return complex_t{re*b, im*b};
return complex_t{ re * b, im * b };
}
complex_t operator/(const float b) {
return complex_t{re/b, im/b};
return complex_t{ re / b, im / b };
}
complex_t operator*(const complex_t& b) {
return complex_t{(re*b.re) - (im*b.im), (im*b.re) + (re*b.im)};
return complex_t{ (re * b.re) - (im * b.im), (im * b.re) + (re * b.im) };
}
complex_t operator+(const complex_t& b) {
return complex_t{re+b.re, im+b.im};
return complex_t{ re + b.re, im + b.im };
}
complex_t operator-(const complex_t& b) {
return complex_t{re-b.re, im-b.im};
return complex_t{ re - b.re, im - b.im };
}
inline complex_t conj() {
return complex_t{re, -im};
return complex_t{ re, -im };
}
inline float phase() {
@ -36,7 +36,7 @@ namespace dsp {
float abs_im = fabsf(im);
float r, angle;
if (re == 0.0f && im == 0.0f) { return 0.0f; }
if (re>=0.0f) {
if (re >= 0.0f) {
r = (re - abs_im) / (re + abs_im);
angle = (FL_M_PI / 4.0f) - (FL_M_PI / 4.0f) * r;
}
@ -51,14 +51,14 @@ namespace dsp {
}
inline float amplitude() {
return sqrt((re*re) + (im*im));
return sqrt((re * re) + (im * im));
}
inline float fastAmplitude() {
float re_abs = fabsf(re);
float im_abs = fabsf(re);
if (re_abs > im_abs) { return re_abs + 0.4f * im_abs; }
return im_abs + 0.4f * re_abs;
return im_abs + 0.4f * re_abs;
}
float re;
@ -67,15 +67,15 @@ namespace dsp {
struct stereo_t {
stereo_t operator*(const float b) {
return stereo_t{l*b, r*b};
return stereo_t{ l * b, r * b };
}
stereo_t operator+(const stereo_t& b) {
return stereo_t{l+b.l, r+b.r};
return stereo_t{ l + b.l, r + b.r };
}
stereo_t operator-(const stereo_t& b) {
return stereo_t{l-b.l, r-b.r};
return stereo_t{ l - b.l, r - b.r };
}
float l;

View File

@ -3,7 +3,7 @@
namespace dsp {
inline uint64_t readBits(int offset, int length, uint8_t* buffer) {
uint64_t outputValue = 0;
int lastBit = offset + (length - 1);
int firstWord = offset / 8;

View File

@ -3,7 +3,7 @@
namespace dsp {
namespace ccsds {
const uint8_t TO_DUAL_BASIS[256] = {
const uint8_t TO_DUAL_BASIS[256] = {
0x00, 0x7b, 0xaf, 0xd4, 0x99, 0xe2, 0x36, 0x4d, 0xfa, 0x81, 0x55, 0x2e, 0x63, 0x18, 0xcc, 0xb7,
0x86, 0xfd, 0x29, 0x52, 0x1f, 0x64, 0xb0, 0xcb, 0x7c, 0x07, 0xd3, 0xa8, 0xe5, 0x9e, 0x4a, 0x31,
0xec, 0x97, 0x43, 0x38, 0x75, 0x0e, 0xda, 0xa1, 0x16, 0x6d, 0xb9, 0xc2, 0x8f, 0xf4, 0x20, 0x5b,
@ -61,9 +61,9 @@ namespace dsp {
};
const uint32_t ASM_VALUE = 0x1ACFFC1D;
const uint8_t ASM_BYTES[4] = {0x1A, 0xCF, 0xFC, 0x1D};
const uint8_t ASM_SYMS[16] = {0b00, 0b01, 0b10, 0b10, 0b11, 0b00, 0b11, 0b11, 0b11, 0b11, 0b11, 0b00, 0b00, 0b01, 0b11, 0b01};
const uint8_t ASM_BITS[32] = {0,0,0,1,1,0,1,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,1};
const uint8_t ASM_BYTES[4] = { 0x1A, 0xCF, 0xFC, 0x1D };
const uint8_t ASM_SYMS[16] = { 0b00, 0b01, 0b10, 0b10, 0b11, 0b00, 0b11, 0b11, 0b11, 0b11, 0b11, 0b00, 0b00, 0b01, 0b11, 0b01 };
const uint8_t ASM_BITS[32] = { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1 };
class FrameDataDecoder {
public:
@ -109,11 +109,10 @@ namespace dsp {
bool _dualBasis;
int _rsBlockSize;
int _rsParitySize;
};
inline void descramble(uint8_t* in, uint8_t* out, int count) {
for (int i = 0; i < count; i++){
for (int i = 0; i < count; i++) {
out[i] = in[i] ^ SCRAMBLING_SEQUENCE[i % 255];
}
}

View File

@ -1,6 +1,6 @@
#pragma once
#include <dsp/types.h>
#define DSP_SIGN(n) ((n) >= 0)
#define DSP_STEP_CPLX(c) (complex_t{(c.re > 0.0f) ? 1.0f : -1.0f, (c.im > 0.0f) ? 1.0f : -1.0f})
#define DSP_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)
#define DSP_SIGN(n) ((n) >= 0)
#define DSP_STEP_CPLX(c) (complex_t{ (c.re > 0.0f) ? 1.0f : -1.0f, (c.im > 0.0f) ? 1.0f : -1.0f })
#define DSP_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)

View File

@ -1,12 +1,12 @@
#pragma once
#include <math.h>
#define FL_M_PI 3.1415926535f
#define FL_M_PI 3.1415926535f
namespace dsp {
namespace math {
inline double sinc(double omega, double x, double norm) {
return (x == 0.0f) ? 1.0f : (sin(omega*x)/(norm*x));
return (x == 0.0f) ? 1.0f : (sin(omega * x) / (norm * x));
}
}
}

View File

@ -4,13 +4,13 @@
namespace dsp {
namespace window_function {
inline double blackman(double n, double N, double alpha = 0.16f) {
double a0 = (1.0f-alpha) / 2.0f;
double a0 = (1.0f - alpha) / 2.0f;
double a2 = alpha / 2.0f;
return a0 - (0.5f*cos(2.0f*FL_M_PI*(n/N))) + (a2*cos(4.0f*FL_M_PI*(n/N)));
return a0 - (0.5f * cos(2.0f * FL_M_PI * (n / N))) + (a2 * cos(4.0f * FL_M_PI * (n / N)));
}
inline double blackmanThirdOrder(double n, double N, double a0, double a1, double a2, double a3) {
return a0 - (a1*cos(2.0f*FL_M_PI*(n/N))) + (a2*cos(4.0f*FL_M_PI*(n/N))) - (a3*cos(6.0f*FL_M_PI*(n/N)));
return a0 - (a1 * cos(2.0f * FL_M_PI * (n / N))) + (a2 * cos(4.0f * FL_M_PI * (n / N))) - (a3 * cos(6.0f * FL_M_PI * (n / N)));
}
inline double nuttall(double n, double N) {

View File

@ -60,7 +60,10 @@ namespace dsp {
void setInSampleRate(float inSampleRate) {
assert(_init);
_inSampleRate = inSampleRate;
if (running) { xlator.stop(); resamp.stop(); }
if (running) {
xlator.stop();
resamp.stop();
}
xlator.setSampleRate(_inSampleRate);
resamp.setInSampleRate(_inSampleRate);
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
@ -68,7 +71,10 @@ namespace dsp {
win.setCutoff(realCutoff);
win.setTransWidth(realCutoff);
resamp.updateWindow(&win);
if (running) { xlator.start(); resamp.start(); }
if (running) {
xlator.start();
resamp.start();
}
}
void setOutSampleRate(float outSampleRate) {
@ -123,6 +129,5 @@ namespace dsp {
stream<complex_t>* _in;
FrequencyXlator<complex_t> xlator;
PolyphaseResampler<complex_t> resamp;
};
}

View File

@ -36,7 +36,7 @@ namespace dsp {
void setCutoff(float cutoff) {
_cutoff = cutoff;
}
void setTransWidth(float transWidth) {
_transWidth = transWidth;
}
@ -67,7 +67,7 @@ namespace dsp {
float sum = 0.0f;
float tc = tapCount;
for (int i = 0; i < tapCount; i++) {
val = math::sinc(omega, (float)i - (tc/2), FL_M_PI) * window_function::blackman(i, tc - 1);
val = math::sinc(omega, (float)i - (tc / 2), FL_M_PI) * window_function::blackman(i, tc - 1);
taps[i] = val;
sum += val;
}
@ -81,7 +81,6 @@ namespace dsp {
private:
float _cutoff, _transWidth, _sampleRate;
};
class BandPassBlackmanWindow : public filter_window::generic_complex_window {
@ -132,7 +131,7 @@ namespace dsp {
_offset = (_lowCutoff + _highCutoff) / 2.0f;
_cutoff = fabs((_highCutoff - _lowCutoff) / 2.0f);
}
void setTransWidth(float transWidth) {
_transWidth = transWidth;
}
@ -163,7 +162,7 @@ namespace dsp {
float sum = 0.0f;
float tc = tapCount;
for (int i = 0; i < tapCount; i++) {
val = math::sinc(omega, (float)i - (tc/2), FL_M_PI) * window_function::blackman(i, tc - 1);
val = math::sinc(omega, (float)i - (tc / 2), FL_M_PI) * window_function::blackman(i, tc - 1);
taps[i].re = val;
taps[i].im = 0;
sum += val;
@ -225,26 +224,24 @@ namespace dsp {
double spb = _sampleRate / _baudRate; // samples per bit/symbol
double scale = 0;
for (int i = 0; i < tapCount; i++)
{
for (int i = 0; i < tapCount; i++) {
double x1, x2, x3, num, den;
double xindx = i - tapCount / 2;
x1 = FL_M_PI * xindx / spb;
x2 = 4 * _alpha * xindx / spb;
x3 = x2 * x2 - 1;
// Avoid Rounding errors...
// Avoid Rounding errors...
if (fabs(x3) >= 0.000001) {
if (i != tapCount / 2)
num = cos((1 + _alpha) * x1) +
sin((1 - _alpha) * x1) / (4 * _alpha * xindx / spb);
sin((1 - _alpha) * x1) / (4 * _alpha * xindx / spb);
else
num = cos((1 + _alpha) * x1) + (1 - _alpha) * FL_M_PI / (4 * _alpha);
den = x3 * FL_M_PI;
}
else {
if (_alpha == 1)
{
if (_alpha == 1) {
taps[i] = -1;
scale += taps[i];
continue;
@ -252,8 +249,8 @@ namespace dsp {
x3 = (1 - _alpha) * x1;
x2 = (1 + _alpha) * x1;
num = (sin(x2) * (1 + _alpha) * FL_M_PI -
cos(x3) * ((1 - _alpha) * FL_M_PI * spb) / (4 * _alpha * xindx) +
sin(x3) * spb * spb / (4 * _alpha * xindx * xindx));
cos(x3) * ((1 - _alpha) * FL_M_PI * spb) / (4 * _alpha * xindx) +
sin(x3) * spb * spb / (4 * _alpha * xindx * xindx));
den = -32 * FL_M_PI * _alpha * _alpha * xindx / spb;
}
taps[i] = 4 * _alpha * num / den;
@ -268,7 +265,6 @@ namespace dsp {
private:
int _tapCount;
float _sampleRate, _baudRate, _alpha;
};
// class NotchWindow : public filter_window::generic_complex_window {
@ -290,8 +286,8 @@ namespace dsp {
// _tapCount = tapCount;
// // Ensure the number of taps is even
// if (_tapCount & 1) { _tapCount++; }
// if (_tapCount & 1) { _tapCount++; }
// fft_in = (complex_t*)fftwf_malloc(_tapCount * sizeof(complex_t));
// fft_out = (complex_t*)fftwf_malloc(_tapCount * sizeof(complex_t));
@ -337,7 +333,7 @@ namespace dsp {
// int thalf = tapCount / 2;
// float start = _frequency - (_width / 2.0f);
// float stop = _frequency + (_width / 2.0f);
// // Fill taps
// float freq;
// float pratio = 2.0f * FL_M_PI / (float)tapCount;
@ -407,7 +403,7 @@ namespace dsp {
// Generate exponential decay
float fact = 1.0f / (float)tapCount;
for (int i = 0; i < tapCount; i++) {
taps[tapCount - i - 1] = {expf(-fact*i) * (float)window_function::blackman(i, tapCount - 1), 0};
taps[tapCount - i - 1] = { expf(-fact * i) * (float)window_function::blackman(i, tapCount - 1), 0 };
}
// Frequency translate it to the right place
@ -419,6 +415,5 @@ namespace dsp {
private:
float _frequency, _sampleRate;
int _tapCount;
};
}