mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-06-30 22:27:51 +02:00
Formatted the entire codebase and added a CI check for formatting
This commit is contained in:
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
@ -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;
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -61,7 +61,6 @@ namespace dsp {
|
||||
|
||||
private:
|
||||
stream<uint8_t>* _in;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
@ -72,7 +72,6 @@ namespace dsp {
|
||||
|
||||
private:
|
||||
stream<uint8_t>* _in;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user