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

@ -17,7 +17,7 @@ AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: false
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false

View File

@ -359,3 +359,12 @@ jobs:
- name: Running codespell
run: cd $GITHUB_WORKSPACE && codespell -q 2 || true
check_formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run check_clang_format
run: cd $GITHUB_WORKSPACE && ./check_clang_format.sh || true

View File

@ -5,7 +5,6 @@
#include <filesystem>
ConfigManager::ConfigManager() {
}
ConfigManager::~ConfigManager() {
@ -96,7 +95,7 @@ void ConfigManager::autoSaveWorker() {
// Sleep but listen for wakeup call
{
std::unique_lock<std::mutex> lock(termMtx);
termCond.wait_for(lock, std::chrono::milliseconds(1000), [this]() { return termFlag; } );
termCond.wait_for(lock, std::chrono::milliseconds(1000), [this]() { return termFlag; });
}
}
}

View File

@ -33,5 +33,4 @@ private:
std::mutex termMtx;
std::condition_variable termCond;
volatile bool termFlag = false;
};

View File

@ -30,11 +30,11 @@
#endif
#ifndef INSTALL_PREFIX
#ifdef __APPLE__
#define INSTALL_PREFIX "/usr/local"
#else
#define INSTALL_PREFIX "/usr"
#endif
#ifdef __APPLE__
#define INSTALL_PREFIX "/usr/local"
#else
#define INSTALL_PREFIX "/usr"
#endif
#endif
const char* OPENGL_VERSIONS_GLSL[] = {
@ -99,7 +99,7 @@ static void maximized_callback(GLFWwindow* window, int n) {
}
// main
int sdrpp_main(int argc, char *argv[]) {
int sdrpp_main(int argc, char* argv[]) {
spdlog::info("SDR++ v" VERSION_STR);
#ifdef IS_MACOS_BUNDLE
@ -321,8 +321,8 @@ int sdrpp_main(int argc, char *argv[]) {
const char* glsl_version = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
// Create window with graphics context
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
@ -343,10 +343,10 @@ int sdrpp_main(int argc, char *argv[]) {
monitor = glfwGetPrimaryMonitor();
core::window = glfwCreateWindow(winWidth, winHeight, "SDR++ v" VERSION_STR " (Built at " __TIME__ ", " __DATE__ ")", NULL, NULL);
if (core::window == NULL) {
spdlog::info("OpenGL {0}.{1} {2}was not supported", OPENGL_VERSIONS_MAJOR[i], OPENGL_VERSIONS_MINOR[i], OPENGL_VERSIONS_IS_ES[i] ? "ES ": "");
spdlog::info("OpenGL {0}.{1} {2}was not supported", OPENGL_VERSIONS_MAJOR[i], OPENGL_VERSIONS_MINOR[i], OPENGL_VERSIONS_IS_ES[i] ? "ES " : "");
continue;
}
spdlog::info("Using OpenGL {0}.{1}{2}", OPENGL_VERSIONS_MAJOR[i], OPENGL_VERSIONS_MINOR[i], OPENGL_VERSIONS_IS_ES[i] ? " ES": "");
spdlog::info("Using OpenGL {0}.{1}{2}", OPENGL_VERSIONS_MAJOR[i], OPENGL_VERSIONS_MINOR[i], OPENGL_VERSIONS_IS_ES[i] ? " ES" : "");
glfwMakeContextCurrent(core::window);
break;
}
@ -370,15 +370,24 @@ int sdrpp_main(int argc, char *argv[]) {
GLFWimage icons[10];
icons[0].pixels = stbi_load(((std::string)(resDir + "/icons/sdrpp.png")).c_str(), &icons[0].width, &icons[0].height, 0, 4);
icons[1].pixels = (unsigned char*)malloc(16 * 16 * 4); icons[1].width = icons[1].height = 16;
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4); icons[2].width = icons[2].height = 24;
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4); icons[3].width = icons[3].height = 32;
icons[4].pixels = (unsigned char*)malloc(48 * 48 * 4); icons[4].width = icons[4].height = 48;
icons[5].pixels = (unsigned char*)malloc(64 * 64 * 4); icons[5].width = icons[5].height = 64;
icons[6].pixels = (unsigned char*)malloc(96 * 96 * 4); icons[6].width = icons[6].height = 96;
icons[7].pixels = (unsigned char*)malloc(128 * 128 * 4); icons[7].width = icons[7].height = 128;
icons[8].pixels = (unsigned char*)malloc(196 * 196 * 4); icons[8].width = icons[8].height = 196;
icons[9].pixels = (unsigned char*)malloc(256 * 256 * 4); icons[9].width = icons[9].height = 256;
icons[1].pixels = (unsigned char*)malloc(16 * 16 * 4);
icons[1].width = icons[1].height = 16;
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4);
icons[2].width = icons[2].height = 24;
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4);
icons[3].width = icons[3].height = 32;
icons[4].pixels = (unsigned char*)malloc(48 * 48 * 4);
icons[4].width = icons[4].height = 48;
icons[5].pixels = (unsigned char*)malloc(64 * 64 * 4);
icons[5].width = icons[5].height = 64;
icons[6].pixels = (unsigned char*)malloc(96 * 96 * 4);
icons[6].width = icons[6].height = 96;
icons[7].pixels = (unsigned char*)malloc(128 * 128 * 4);
icons[7].width = icons[7].height = 128;
icons[8].pixels = (unsigned char*)malloc(196 * 196 * 4);
icons[8].width = icons[8].height = 196;
icons[9].pixels = (unsigned char*)malloc(256 * 256 * 4);
icons[9].width = icons[9].height = 256;
stbir_resize_uint8(icons[0].pixels, icons[0].width, icons[0].height, icons[0].width * 4, icons[1].pixels, 16, 16, 16 * 4, 4);
stbir_resize_uint8(icons[0].pixels, icons[0].width, icons[0].height, icons[0].width * 4, icons[2].pixels, 24, 24, 24 * 4, 4);
stbir_resize_uint8(icons[0].pixels, icons[0].width, icons[0].height, icons[0].width * 4, icons[3].pixels, 32, 32, 32 * 4, 4);
@ -403,7 +412,8 @@ int sdrpp_main(int argc, char *argv[]) {
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGuiIO& io = ImGui::GetIO();
(void)io;
io.IniFilename = NULL;
// Setup Platform/Renderer bindings
@ -445,7 +455,7 @@ int sdrpp_main(int argc, char *argv[]) {
fsWidth = _winWidth;
fsHeight = _winHeight;
glfwGetWindowPos(core::window, &fsPosX, &fsPosY);
const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowMonitor(core::window, monitor, 0, 0, mode->width, mode->height, 0);
}
@ -467,7 +477,7 @@ int sdrpp_main(int argc, char *argv[]) {
if (_maximized != maximized) {
_maximized = maximized;
core::configManager.acquire();
core::configManager.conf["maximized"]= _maximized;
core::configManager.conf["maximized"] = _maximized;
if (!maximized) {
glfwSetWindowSize(core::window, core::configManager.conf["windowSize"]["w"], core::configManager.conf["windowSize"]["h"]);
}
@ -483,7 +493,7 @@ int sdrpp_main(int argc, char *argv[]) {
fsWidth = _winWidth;
fsHeight = _winHeight;
glfwGetWindowPos(core::window, &fsPosX, &fsPosY);
const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowMonitor(core::window, monitor, 0, 0, mode->width, mode->height, 0);
core::configManager.acquire();
core::configManager.conf["fullscreen"] = true;
@ -491,7 +501,7 @@ int sdrpp_main(int argc, char *argv[]) {
}
else {
spdlog::info("Fullscreen: OFF");
glfwSetWindowMonitor(core::window, nullptr, fsPosX, fsPosY, fsWidth, fsHeight, 0);
glfwSetWindowMonitor(core::window, nullptr, fsPosX, fsPosY, fsWidth, fsHeight, 0);
core::configManager.acquire();
core::configManager.conf["fullscreen"] = false;
core::configManager.release();

View File

@ -12,4 +12,4 @@ namespace core {
void setInputSampleRate(double samplerate);
};
int sdrpp_main(int argc, char *argv[]);
int sdrpp_main(int argc, char* argv[]);

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

@ -76,7 +76,7 @@ namespace dsp {
private:
void workerLoop() {
while (run() >= 0);
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

@ -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);
}
@ -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
@ -354,6 +357,5 @@ namespace dsp {
int sizes[TEST_BUFFER_SIZE];
bool stopWorker = false;
};
};

View File

@ -203,6 +203,5 @@ namespace dsp {
stream<T>* _input;
std::vector<ChainLinkAny<T>*> links;
bool running = false;
};
}

View File

@ -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() {}
@ -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
@ -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

@ -92,7 +92,6 @@ namespace dsp {
private:
stream<complex_t>* _in;
PCMType _pcmType;
};
class DynamicRangeDecompressor : public generic_block<DynamicRangeDecompressor> {
@ -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,8 +136,6 @@ 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++;
}
@ -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,7 +21,7 @@ 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);
@ -87,13 +87,13 @@ namespace dsp {
bitsRead = 0;
continue;
}
}
else { i++; }
else {
i++;
}
nextBitIsStartOfFrame = false;
}
// Keep last _syncLen4 symbols
@ -125,13 +125,12 @@ namespace dsp {
int callcount = 0;
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,7 +152,7 @@ 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);
@ -208,7 +207,6 @@ namespace dsp {
}
i++;
}
// Keep last _syncLen symbols
@ -230,7 +228,6 @@ namespace dsp {
int bitsRead = -1;
stream<float>* _in;
};
class SymbolDeframer : public generic_block<SymbolDeframer> {
@ -242,7 +239,7 @@ 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);
@ -297,7 +294,6 @@ namespace dsp {
}
i++;
}
// Keep last _syncLen symbols
@ -319,7 +315,6 @@ namespace dsp {
int bitsRead = -1;
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> {
@ -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,18 +370,17 @@ 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;
@ -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;
@ -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;
@ -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;

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
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[] = {
@ -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;
@ -129,6 +143,5 @@ namespace dsp {
correct_reed_solomon* rs;
stream<uint8_t>* _in;
};
}

View File

@ -92,8 +92,7 @@ namespace dsp {
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();
@ -123,6 +121,5 @@ namespace dsp {
uint8_t packet[0x4008];
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

@ -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,21 +30,21 @@ 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,21 +86,21 @@ 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));
@ -189,7 +189,6 @@ namespace dsp {
complex_t* fft_fcout;
int _tapCount;
};
class FFTNoiseReduction : public generic_block<FFTNoiseReduction> {
@ -214,19 +213,19 @@ 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));
@ -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);
@ -379,7 +378,6 @@ namespace dsp {
float _level;
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,7 +103,6 @@ namespace dsp {
// Calculate output
lastVCO.re = cosf(-vcoPhase);
lastVCO.im = sinf(-vcoPhase);
}
_in->flush();
@ -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,8 +190,10 @@ 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; }
@ -196,7 +201,9 @@ namespace dsp {
// 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,7 +213,6 @@ namespace dsp {
// Calculate output
lastVCO.re = cosf(vcoPhase);
lastVCO.im = sinf(vcoPhase);
}
_in->flush();
@ -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,7 +309,6 @@ namespace dsp {
// Calculate output
lastVCO.re = cosf(vcoPhase);
lastVCO.im = sinf(vcoPhase);
}
_in->flush();
@ -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> {
@ -225,7 +223,6 @@ namespace dsp {
float _rate = 10e-4;
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> {
@ -431,7 +425,6 @@ namespace dsp {
float* normBuffer;
float _level = -50.0f;
stream<complex_t>* _in;
};
template <class T>
@ -497,7 +490,6 @@ namespace dsp {
int samples = 1;
int read = 0;
stream<T>* _in;
};
class Threshold : public generic_block<Threshold> {
@ -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>
@ -110,7 +109,6 @@ namespace dsp {
}
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();
@ -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);
@ -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,7 +51,7 @@ namespace dsp {
}
inline float amplitude() {
return sqrt((re*re) + (im*im));
return sqrt((re * re) + (im * im));
}
inline float fastAmplitude() {
@ -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

@ -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

@ -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 {
@ -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 {
@ -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;
};
}

View File

@ -36,7 +36,7 @@ namespace colormaps {
map.entryCount = mapTxt.size();
map.map = new float[mapTxt.size() * 3];
int i = 0;
for(auto const& col : mapTxt) {
for (auto const& col : mapTxt) {
uint8_t r, g, b, a;
map.map[i * 3] = std::stoi(col.substr(1, 2), NULL, 16);
map.map[(i * 3) + 1] = std::stoi(col.substr(3, 2), NULL, 16);

View File

@ -10,14 +10,13 @@ namespace credits {
ImFont* bigFont;
void init() {
}
void show() {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 20.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0,0,0,0));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImVec2 dispSize = ImGui::GetIO().DisplaySize;
ImVec2 center = ImVec2(dispSize.x/2.0f, dispSize.y/2.0f);
ImVec2 center = ImVec2(dispSize.x / 2.0f, dispSize.y / 2.0f);
ImGui::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup("Credits");
ImGui::BeginPopupModal("Credits", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);

View File

@ -4,19 +4,19 @@
#include <string>
#include <gui/gui.h>
#define GENERIC_DIALOG_BUTTONS_OK "Ok\0"
#define GENERIC_DIALOG_BUTTONS_YES_NO "Yes\0No\0"
#define GENERIC_DIALOG_BUTTONS_APPLY_CANCEL "Apply\0Cancel\0"
#define GENERIC_DIALOG_BUTTONS_OK_CANCEL "Ok\0Cancel\0"
#define GENERIC_DIALOG_BUTTONS_OK "Ok\0"
#define GENERIC_DIALOG_BUTTONS_YES_NO "Yes\0No\0"
#define GENERIC_DIALOG_BUTTONS_APPLY_CANCEL "Apply\0Cancel\0"
#define GENERIC_DIALOG_BUTTONS_OK_CANCEL "Ok\0Cancel\0"
#define GENERIC_DIALOG_BUTTON_OK 0
#define GENERIC_DIALOG_BUTTON_YES 0
#define GENERIC_DIALOG_BUTTON_NO 1
#define GENERIC_DIALOG_BUTTON_APPLY 0
#define GENERIC_DIALOG_BUTTON_CANCE 1
#define GENERIC_DIALOG_BUTTON_OK 0
#define GENERIC_DIALOG_BUTTON_YES 0
#define GENERIC_DIALOG_BUTTON_NO 1
#define GENERIC_DIALOG_BUTTON_APPLY 0
#define GENERIC_DIALOG_BUTTON_CANCE 1
namespace ImGui {
template<typename Func>
template <typename Func>
int GenericDialog(const char* id, bool& open, const char* buttons, Func draw) {
// If not open, return
if (!open) { return -1; }

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ namespace icons {
ImTextureID CENTER_TUNING;
GLuint loadTexture(std::string path) {
int w,h,n;
int w, h, n;
stbi_uc* data = stbi_load(path.c_str(), &w, &h, &n, 0);
GLuint texId;
glGenTextures(1, &texId);

View File

@ -49,10 +49,22 @@ void MainWindow::init() {
// Load menu elements
gui::menu.order.clear();
for (auto& elem : menuElements) {
if (!elem.contains("name")) { spdlog::error("Menu element is missing name key"); continue; }
if (!elem["name"].is_string()) { spdlog::error("Menu element name isn't a string"); continue; }
if (!elem.contains("open")) { spdlog::error("Menu element is missing open key"); continue; }
if (!elem["open"].is_boolean()) { spdlog::error("Menu element name isn't a string"); continue; }
if (!elem.contains("name")) {
spdlog::error("Menu element is missing name key");
continue;
}
if (!elem["name"].is_string()) {
spdlog::error("Menu element name isn't a string");
continue;
}
if (!elem.contains("open")) {
spdlog::error("Menu element is missing open key");
continue;
}
if (!elem["open"].is_boolean()) {
spdlog::error("Menu element name isn't a string");
continue;
}
Menu::MenuOption_t opt;
opt.name = elem["name"];
opt.open = elem["open"];
@ -73,8 +85,8 @@ void MainWindow::init() {
gui::waterfall.setBandwidth(8000000);
gui::waterfall.setViewBandwidth(8000000);
fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fft_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fft_in = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fft_out = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fftwPlan = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
sigpath::signalPath.init(8000000, 20, fftSize, &dummyStream, (dsp::complex_t*)fft_in, fftHandler, this);
@ -88,7 +100,7 @@ void MainWindow::init() {
// Load modules from /module directory
if (std::filesystem::is_directory(modulesDir)) {
for (const auto & file : std::filesystem::directory_iterator(modulesDir)) {
for (const auto& file : std::filesystem::directory_iterator(modulesDir)) {
std::string path = file.path().generic_string();
if (file.path().extension().generic_string() != SDRPP_MOD_EXTENTSION) {
continue;
@ -130,7 +142,7 @@ void MainWindow::init() {
LoadingScreen::show("Loading color maps");
spdlog::info("Loading color maps");
if (std::filesystem::is_directory(resourcesDir + "/colormaps")) {
for (const auto & file : std::filesystem::directory_iterator(resourcesDir + "/colormaps")) {
for (const auto& file : std::filesystem::directory_iterator(resourcesDir + "/colormaps")) {
std::string path = file.path().generic_string();
LoadingScreen::show("Loading " + path);
spdlog::info("Loading {0}", path);
@ -196,11 +208,11 @@ void MainWindow::init() {
float finalBwHalf = gui::waterfall.getBandwidth() / 2.0;
for (auto& [_name, _vfo] : gui::waterfall.vfos) {
if (_vfo->lowerOffset < -finalBwHalf) {
sigpath::vfoManager.setCenterOffset(_name, (_vfo->bandwidth/2)-finalBwHalf);
sigpath::vfoManager.setCenterOffset(_name, (_vfo->bandwidth / 2) - finalBwHalf);
continue;
}
if (_vfo->upperOffset > finalBwHalf) {
sigpath::vfoManager.setCenterOffset(_name, finalBwHalf-(_vfo->bandwidth/2));
sigpath::vfoManager.setCenterOffset(_name, finalBwHalf - (_vfo->bandwidth / 2));
continue;
}
}
@ -224,7 +236,7 @@ void MainWindow::fftHandler(dsp::complex_t* samples, int count, void* ctx) {
// Zero out the rest of the samples
if (count < _this->fftSize) {
memset(&_this->fft_in[count], 0, (_this->fftSize-count) * sizeof(dsp::complex_t));
memset(&_this->fft_in[count], 0, (_this->fftSize - count) * sizeof(dsp::complex_t));
}
// Execute FFT
@ -258,14 +270,12 @@ void MainWindow::vfoAddedHandler(VFOManager::VFO* vfo, void* ctx) {
double viewBW = gui::waterfall.getViewBandwidth();
double viewOffset = gui::waterfall.getViewOffset();
double viewLower = viewOffset - (viewBW/2.0);
double viewUpper = viewOffset + (viewBW/2.0);
double viewLower = viewOffset - (viewBW / 2.0);
double viewUpper = viewOffset + (viewBW / 2.0);
double newOffset = std::clamp<double>(offset, viewLower, viewUpper);
sigpath::vfoManager.setCenterOffset(name, _this->initComplete ? newOffset : offset);
}
void MainWindow::draw() {
@ -415,7 +425,7 @@ void MainWindow::draw() {
int snrWidth = std::min<int>(300, ImGui::GetWindowSize().x - ImGui::GetCursorPosX() - 87);
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (snrWidth+87));
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (snrWidth + 87));
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5);
ImGui::SetNextItemWidth(snrWidth);
ImGui::SNRMeter((vfo != NULL) ? gui::waterfall.selectedVFOSNR : 0);
@ -456,7 +466,7 @@ void MainWindow::draw() {
else {
ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
}
if(!down && grabbingMenu) {
if (!down && grabbingMenu) {
grabbingMenu = false;
menuWidth = newWidth;
core::configManager.acquire();
@ -500,7 +510,7 @@ void MainWindow::draw() {
firstMenuRender = false;
}
if(ImGui::CollapsingHeader("Debug")) {
if (ImGui::CollapsingHeader("Debug")) {
ImGui::Text("Frame time: %.3f ms/frame", 1000.0 / ImGui::GetIO().Framerate);
ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate);
ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency());

View File

@ -9,7 +9,7 @@
#include <mutex>
#include <gui/tuner.h>
#define WINDOW_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground
#define WINDOW_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground
class MainWindow {
public:
@ -64,5 +64,4 @@ private:
bool initComplete = false;
EventHandler<VFOManager::VFO*> vfoCreatedHandler;
};

View File

@ -21,7 +21,7 @@ namespace bandplanmenu {
if (bandplan::bandplans.find(core::configManager.conf["bandPlan"]) != bandplan::bandplans.end()) {
std::string name = core::configManager.conf["bandPlan"];
bandplanId = std::distance(bandplan::bandplanNames.begin(), std::find(bandplan::bandplanNames.begin(),
bandplan::bandplanNames.end(), name));
bandplan::bandplanNames.end(), name));
gui::waterfall.bandplan = &bandplan::bandplans[name];
}
else {

View File

@ -33,15 +33,15 @@ namespace displaymenu {
};
const char* FFTSizesStr = "524288\0"
"262144\0"
"131072\0"
"65536\0"
"32768\0"
"16384\0"
"8192\0"
"4096\0"
"2048\0"
"1024\0";
"262144\0"
"131072\0"
"65536\0"
"32768\0"
"16384\0"
"8192\0"
"4096\0"
"2048\0"
"1024\0";
int fftSizeId = 0;
@ -83,7 +83,7 @@ namespace displaymenu {
fftRate = core::configManager.conf["fftRate"];
sigpath::signalPath.setFFTRate(fftRate);
selectedWindow = std::clamp<int>((int)core::configManager.conf["fftWindow"], 0, _FFT_WINDOW_COUNT-1);
selectedWindow = std::clamp<int>((int)core::configManager.conf["fftWindow"], 0, _FFT_WINDOW_COUNT - 1);
gui::mainWindow.setFFTWindow(selectedWindow);
}
@ -153,7 +153,5 @@ namespace displaymenu {
}
ImGui::Text("Color map Author: %s", colorMapAuthor.c_str());
}
}
}

View File

@ -51,7 +51,7 @@ namespace module_manager_menu {
ImGui::TableSetColumnIndex(2);
ImVec2 origPos = ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(origPos.x - 3, origPos.y));
if (ImGui::Button(("##module_mgr_"+name).c_str(), ImVec2(height,height))) {
if (ImGui::Button(("##module_mgr_" + name).c_str(), ImVec2(height, height))) {
toBeRemoved = name;
confirmOpened = true;
}
@ -61,14 +61,14 @@ namespace module_manager_menu {
ImGui::EndTable();
}
if (ImGui::GenericDialog("module_mgr_confirm_", confirmOpened, GENERIC_DIALOG_BUTTONS_YES_NO, [](){
ImGui::Text("Deleting \"%s\". Are you sure?", toBeRemoved.c_str());
}) == GENERIC_DIALOG_BUTTON_YES) {
if (ImGui::GenericDialog("module_mgr_confirm_", confirmOpened, GENERIC_DIALOG_BUTTONS_YES_NO, []() {
ImGui::Text("Deleting \"%s\". Are you sure?", toBeRemoved.c_str());
}) == GENERIC_DIALOG_BUTTON_YES) {
core::moduleManager.deleteInstance(toBeRemoved);
modified = true;
}
ImGui::GenericDialog("module_mgr_error_", errorOpen, GENERIC_DIALOG_BUTTONS_OK, [](){
ImGui::GenericDialog("module_mgr_error_", errorOpen, GENERIC_DIALOG_BUTTONS_OK, []() {
ImGui::Text(errorMessage.c_str());
});
@ -89,7 +89,7 @@ namespace module_manager_menu {
ImGui::TableSetColumnIndex(2);
if (strlen(modName) == 0) { style::beginDisabled(); }
if (ImGui::Button("+##module_mgr_add_btn", ImVec2(16,0))) {
if (ImGui::Button("+##module_mgr_add_btn", ImVec2(16, 0))) {
if (!core::moduleManager.createInstance(modName, modTypes[modTypeId])) {
core::moduleManager.postInit(modName);
modified = true;

View File

@ -34,29 +34,41 @@ namespace sourecmenu {
};
const char* offsetModesTxt = "None\0"
"Custom\0"
"SpyVerter\0"
"Ham-It-Up\0"
"DK5AV X-Band\0"
"Ku LNB (9750MHz)\0"
"Ku LNB (10700MHz)\0";
"Custom\0"
"SpyVerter\0"
"Ham-It-Up\0"
"DK5AV X-Band\0"
"Ku LNB (9750MHz)\0"
"Ku LNB (10700MHz)\0";
const char* decimationStages = "None\0"
"2\0"
"4\0"
"8\0"
"16\0"
"32\0"
"64\0";
"2\0"
"4\0"
"8\0"
"16\0"
"32\0"
"64\0";
void updateOffset() {
if (offsetMode == OFFSET_MODE_CUSTOM) { effectiveOffset = customOffset; }
else if (offsetMode == OFFSET_MODE_SPYVERTER) { effectiveOffset = 120000000; } // 120MHz Up-conversion
else if (offsetMode == OFFSET_MODE_HAM_IT_UP) { effectiveOffset = 125000000; } // 125MHz Up-conversion
else if (offsetMode == OFFSET_MODE_DK5AV_XB) { effectiveOffset = -6800000000; } // 6.8GHz Down-conversion
else if (offsetMode == OFFSET_MODE_KU_LNB_9750) { effectiveOffset = -9750000000; } // 9.750GHz Down-conversion
else if (offsetMode == OFFSET_MODE_KU_LNB_10700) { effectiveOffset = -10700000000; } // 10.7GHz Down-conversion
else { effectiveOffset = 0; }
if (offsetMode == OFFSET_MODE_CUSTOM) { effectiveOffset = customOffset; }
else if (offsetMode == OFFSET_MODE_SPYVERTER) {
effectiveOffset = 120000000;
} // 120MHz Up-conversion
else if (offsetMode == OFFSET_MODE_HAM_IT_UP) {
effectiveOffset = 125000000;
} // 125MHz Up-conversion
else if (offsetMode == OFFSET_MODE_DK5AV_XB) {
effectiveOffset = -6800000000;
} // 6.8GHz Down-conversion
else if (offsetMode == OFFSET_MODE_KU_LNB_9750) {
effectiveOffset = -9750000000;
} // 9.750GHz Down-conversion
else if (offsetMode == OFFSET_MODE_KU_LNB_10700) {
effectiveOffset = -10700000000;
} // 10.7GHz Down-conversion
else {
effectiveOffset = 0;
}
sigpath::sourceManager.setTuningOffset(effectiveOffset);
}

View File

@ -120,7 +120,7 @@ namespace vfo_color_menu {
if (vfoColors.find(name) != vfoColors.end()) {
col = vfoColors[name];
}
if (ImGui::ColorEdit3(("##vfo_color_"+name).c_str(), (float*)&col, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) {
if (ImGui::ColorEdit3(("##vfo_color_" + name).c_str(), (float*)&col, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) {
vfoColors[name] = col;
vfo->color = IM_COL32((int)roundf(col.x * 255), (int)roundf(col.y * 255), (int)roundf(col.z * 255), 50);
core::configManager.acquire();

View File

@ -27,7 +27,7 @@ bool ThemeManager::loadThemesFromDir(std::string path) {
return false;
}
themes.clear();
for (const auto & file : std::filesystem::directory_iterator(path)) {
for (const auto& file : std::filesystem::directory_iterator(path)) {
std::string _path = file.path().generic_string();
if (file.path().extension().generic_string() != ".json") {
continue;
@ -142,20 +142,20 @@ bool ThemeManager::applyTheme(std::string name) {
if (param == "WaterfallBackground") {
decodeRGBA(val, ret);
waterfallBg = ImVec4((float)ret[0]/255.0f, (float)ret[1]/255.0f, (float)ret[2]/255.0f, (float)ret[3]/255.0f);
waterfallBg = ImVec4((float)ret[0] / 255.0f, (float)ret[1] / 255.0f, (float)ret[2] / 255.0f, (float)ret[3] / 255.0f);
continue;
}
if (param == "ClearColor") {
decodeRGBA(val, ret);
clearColor = ImVec4((float)ret[0]/255.0f, (float)ret[1]/255.0f, (float)ret[2]/255.0f, (float)ret[3]/255.0f);
clearColor = ImVec4((float)ret[0] / 255.0f, (float)ret[1] / 255.0f, (float)ret[2] / 255.0f, (float)ret[3] / 255.0f);
continue;
}
// If param is a color, check that it's a valid RGBA hex value
if (IMGUI_COL_IDS.find(param) != IMGUI_COL_IDS.end()) {
decodeRGBA(val, ret);
colors[IMGUI_COL_IDS[param]] = ImVec4((float)ret[0]/255.0f, (float)ret[1]/255.0f, (float)ret[2]/255.0f, (float)ret[3]/255.0f);
colors[IMGUI_COL_IDS[param]] = ImVec4((float)ret[0] / 255.0f, (float)ret[1] / 255.0f, (float)ret[2] / 255.0f, (float)ret[3] / 255.0f);
continue;
}
}
@ -181,57 +181,57 @@ std::vector<std::string> ThemeManager::getThemeNames() {
}
std::map<std::string, int> ThemeManager::IMGUI_COL_IDS = {
{"Text", ImGuiCol_Text},
{"TextDisabled", ImGuiCol_TextDisabled},
{"WindowBg", ImGuiCol_WindowBg},
{"ChildBg", ImGuiCol_ChildBg},
{"PopupBg", ImGuiCol_PopupBg},
{"Border", ImGuiCol_Border},
{"BorderShadow", ImGuiCol_BorderShadow},
{"FrameBg", ImGuiCol_FrameBg},
{"FrameBgHovered", ImGuiCol_FrameBgHovered},
{"FrameBgActive", ImGuiCol_FrameBgActive},
{"TitleBg", ImGuiCol_TitleBg},
{"TitleBgActive", ImGuiCol_TitleBgActive},
{"TitleBgCollapsed", ImGuiCol_TitleBgCollapsed},
{"MenuBarBg", ImGuiCol_MenuBarBg},
{"ScrollbarBg", ImGuiCol_ScrollbarBg},
{"ScrollbarGrab", ImGuiCol_ScrollbarGrab},
{"ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered},
{"ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive},
{"CheckMark", ImGuiCol_CheckMark},
{"SliderGrab", ImGuiCol_SliderGrab},
{"SliderGrabActive", ImGuiCol_SliderGrabActive},
{"Button", ImGuiCol_Button},
{"ButtonHovered", ImGuiCol_ButtonHovered},
{"ButtonActive", ImGuiCol_ButtonActive},
{"Header", ImGuiCol_Header},
{"HeaderHovered", ImGuiCol_HeaderHovered},
{"HeaderActive", ImGuiCol_HeaderActive},
{"Separator", ImGuiCol_Separator},
{"SeparatorHovered", ImGuiCol_SeparatorHovered},
{"SeparatorActive", ImGuiCol_SeparatorActive},
{"ResizeGrip", ImGuiCol_ResizeGrip},
{"ResizeGripHovered", ImGuiCol_ResizeGripHovered},
{"ResizeGripActive", ImGuiCol_ResizeGripActive},
{"Tab", ImGuiCol_Tab},
{"TabHovered", ImGuiCol_TabHovered},
{"TabActive", ImGuiCol_TabActive},
{"TabUnfocused", ImGuiCol_TabUnfocused},
{"TabUnfocusedActive", ImGuiCol_TabUnfocusedActive},
{"PlotLines", ImGuiCol_PlotLines},
{"PlotLinesHovered", ImGuiCol_PlotLinesHovered},
{"PlotHistogram", ImGuiCol_PlotHistogram},
{"PlotHistogramHovered", ImGuiCol_PlotHistogramHovered},
{"TableHeaderBg", ImGuiCol_TableHeaderBg},
{"TableBorderStrong", ImGuiCol_TableBorderStrong},
{"TableBorderLight", ImGuiCol_TableBorderLight},
{"TableRowBg", ImGuiCol_TableRowBg},
{"TableRowBgAlt", ImGuiCol_TableRowBgAlt},
{"TextSelectedBg", ImGuiCol_TextSelectedBg},
{"DragDropTarget", ImGuiCol_DragDropTarget},
{"NavHighlight", ImGuiCol_NavHighlight},
{"NavWindowingHighlight", ImGuiCol_NavWindowingHighlight},
{"NavWindowingDimBg", ImGuiCol_NavWindowingDimBg},
{"ModalWindowDimBg", ImGuiCol_ModalWindowDimBg}
{ "Text", ImGuiCol_Text },
{ "TextDisabled", ImGuiCol_TextDisabled },
{ "WindowBg", ImGuiCol_WindowBg },
{ "ChildBg", ImGuiCol_ChildBg },
{ "PopupBg", ImGuiCol_PopupBg },
{ "Border", ImGuiCol_Border },
{ "BorderShadow", ImGuiCol_BorderShadow },
{ "FrameBg", ImGuiCol_FrameBg },
{ "FrameBgHovered", ImGuiCol_FrameBgHovered },
{ "FrameBgActive", ImGuiCol_FrameBgActive },
{ "TitleBg", ImGuiCol_TitleBg },
{ "TitleBgActive", ImGuiCol_TitleBgActive },
{ "TitleBgCollapsed", ImGuiCol_TitleBgCollapsed },
{ "MenuBarBg", ImGuiCol_MenuBarBg },
{ "ScrollbarBg", ImGuiCol_ScrollbarBg },
{ "ScrollbarGrab", ImGuiCol_ScrollbarGrab },
{ "ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered },
{ "ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive },
{ "CheckMark", ImGuiCol_CheckMark },
{ "SliderGrab", ImGuiCol_SliderGrab },
{ "SliderGrabActive", ImGuiCol_SliderGrabActive },
{ "Button", ImGuiCol_Button },
{ "ButtonHovered", ImGuiCol_ButtonHovered },
{ "ButtonActive", ImGuiCol_ButtonActive },
{ "Header", ImGuiCol_Header },
{ "HeaderHovered", ImGuiCol_HeaderHovered },
{ "HeaderActive", ImGuiCol_HeaderActive },
{ "Separator", ImGuiCol_Separator },
{ "SeparatorHovered", ImGuiCol_SeparatorHovered },
{ "SeparatorActive", ImGuiCol_SeparatorActive },
{ "ResizeGrip", ImGuiCol_ResizeGrip },
{ "ResizeGripHovered", ImGuiCol_ResizeGripHovered },
{ "ResizeGripActive", ImGuiCol_ResizeGripActive },
{ "Tab", ImGuiCol_Tab },
{ "TabHovered", ImGuiCol_TabHovered },
{ "TabActive", ImGuiCol_TabActive },
{ "TabUnfocused", ImGuiCol_TabUnfocused },
{ "TabUnfocusedActive", ImGuiCol_TabUnfocusedActive },
{ "PlotLines", ImGuiCol_PlotLines },
{ "PlotLinesHovered", ImGuiCol_PlotLinesHovered },
{ "PlotHistogram", ImGuiCol_PlotHistogram },
{ "PlotHistogramHovered", ImGuiCol_PlotHistogramHovered },
{ "TableHeaderBg", ImGuiCol_TableHeaderBg },
{ "TableBorderStrong", ImGuiCol_TableBorderStrong },
{ "TableBorderLight", ImGuiCol_TableBorderLight },
{ "TableRowBg", ImGuiCol_TableRowBg },
{ "TableRowBgAlt", ImGuiCol_TableRowBgAlt },
{ "TextSelectedBg", ImGuiCol_TextSelectedBg },
{ "DragDropTarget", ImGuiCol_DragDropTarget },
{ "NavHighlight", ImGuiCol_NavHighlight },
{ "NavWindowingHighlight", ImGuiCol_NavWindowingHighlight },
{ "NavWindowingDimBg", ImGuiCol_NavWindowingDimBg },
{ "ModalWindowDimBg", ImGuiCol_ModalWindowDimBg }
};

View File

@ -20,7 +20,8 @@ public:
std::vector<std::string> getThemeNames();
ImVec4 waterfallBg = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);;
ImVec4 waterfallBg = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
;
ImVec4 clearColor = ImVec4(0.0666f, 0.0666f, 0.0666f, 1.0f);
private:
@ -29,5 +30,4 @@ private:
static std::map<std::string, int> IMGUI_COL_IDS;
std::map<std::string, Theme> themes;
};

View File

@ -31,7 +31,7 @@ namespace tuner {
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[vfoName];
double currentOff = vfo->centerOffset;
double currentOff = vfo->centerOffset;
double currentTune = gui::waterfall.getCenterFrequency() + vfo->generalOffset;
double delta = freq - currentTune;
@ -119,21 +119,21 @@ namespace tuner {
void tune(int mode, std::string vfoName, double freq) {
switch (mode) {
case TUNER_MODE_CENTER:
centerTuning(vfoName, freq);
break;
case TUNER_MODE_NORMAL:
normalTuning(vfoName, freq);
break;
case TUNER_MODE_LOWER_HALF:
normalTuning(vfoName, freq);
break;
case TUNER_MODE_UPPER_HALF:
normalTuning(vfoName, freq);
break;
case TUNER_MODE_IQ_ONLY:
iqTuning(freq);
break;
case TUNER_MODE_CENTER:
centerTuning(vfoName, freq);
break;
case TUNER_MODE_NORMAL:
normalTuning(vfoName, freq);
break;
case TUNER_MODE_LOWER_HALF:
normalTuning(vfoName, freq);
break;
case TUNER_MODE_UPPER_HALF:
normalTuning(vfoName, freq);
break;
case TUNER_MODE_IQ_ONLY:
iqTuning(freq);
break;
}
}
}

View File

@ -21,10 +21,10 @@ namespace bandplan {
void to_json(json& j, const Band_t& b) {
j = json{
{"name", b.name},
{"type", b.type},
{"start", b.start},
{"end", b.end},
{ "name", b.name },
{ "type", b.type },
{ "start", b.start },
{ "end", b.end },
};
}
@ -37,12 +37,12 @@ namespace bandplan {
void to_json(json& j, const BandPlan_t& b) {
j = json{
{"name", b.name},
{"country_name", b.countryName},
{"country_code", b.countryCode},
{"author_name", b.authorName},
{"author_url", b.authorURL},
{"bands", b.bands}
{ "name", b.name },
{ "country_name", b.countryName },
{ "country_code", b.countryCode },
{ "author_name", b.authorName },
{ "author_url", b.authorURL },
{ "bands", b.bands }
};
}
@ -99,7 +99,7 @@ namespace bandplan {
return;
}
bandplans.clear();
for (const auto & file : std::filesystem::directory_iterator(path)) {
for (const auto& file : std::filesystem::directory_iterator(path)) {
std::string path = file.path().generic_string();
if (file.path().extension().generic_string() != ".json") {
continue;

View File

@ -12,7 +12,7 @@ namespace ImGui {
float pad = style.FramePadding.y;
ImVec2 min = window->DC.CursorPos;
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), CalcItemWidth());
ImRect bb(min, ImVec2(min.x+size.x, min.y+size.y));
ImRect bb(min, ImVec2(min.x + size.x, min.y + size.y));
float lineHeight = size.y;
ItemSize(size, style.FramePadding.y);
@ -20,13 +20,13 @@ namespace ImGui {
return;
}
window->DrawList->AddRectFilled(min, ImVec2(min.x+size.x, min.y+size.y), IM_COL32(0,0,0,255));
window->DrawList->AddRectFilled(min, ImVec2(min.x + size.x, min.y + size.y), IM_COL32(0, 0, 0, 255));
ImU32 col = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
float increment = size.x / 1024.0f;
for (int i = 0; i < 1024; i++) {
if (buffer[i].re > 1.5f || buffer[i].re < -1.5f) { continue; }
if (buffer[i].im > 1.5f || buffer[i].im < -1.5f) { continue; }
window->DrawList->AddCircleFilled(ImVec2((((buffer[i].re / 1.5f) + 1) * (size.x*0.5f)) + min.x, (((buffer[i].im / 1.5f) + 1) * (size.y*0.5f)) + min.y), 2, col);
window->DrawList->AddCircleFilled(ImVec2((((buffer[i].re / 1.5f) + 1) * (size.x * 0.5f)) + min.x, (((buffer[i].im / 1.5f) + 1) * (size.y * 0.5f)) + min.y), 2, col);
}
}

View File

@ -20,6 +20,5 @@ namespace ImGui {
private:
std::mutex bufferMtx;
dsp::complex_t buffer[1024];
};
}

View File

@ -63,15 +63,15 @@ bool FileSelect::pathIsValid() {
}
void FileSelect::worker() {
auto file = pfd::open_file("Open File", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "", _filter);
std::vector<std::string> res = file.result();
auto file = pfd::open_file("Open File", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "", _filter);
std::vector<std::string> res = file.result();
if (res.size() > 0) {
path = res[0];
strcpy(strPath, path.c_str());
pathChanged = true;
}
if (res.size() > 0) {
path = res[0];
strcpy(strPath, path.c_str());
pathChanged = true;
}
pathValid = std::filesystem::is_regular_file(expandString(path));
dialogOpen = false;
pathValid = std::filesystem::is_regular_file(expandString(path));
dialogOpen = false;
}

View File

@ -8,7 +8,7 @@
class FileSelect {
public:
FileSelect(std::string defaultPath, std::vector<std::string> filter = {"All Files", "*"});
FileSelect(std::string defaultPath, std::vector<std::string> filter = { "All Files", "*" });
bool render(std::string id);
void setPath(std::string path, bool markChanged = false);
bool pathIsValid();

View File

@ -62,15 +62,15 @@ bool FolderSelect::pathIsValid() {
}
void FolderSelect::worker() {
auto fold = pfd::select_folder("Select Folder", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "");
std::string res = fold.result();
auto fold = pfd::select_folder("Select Folder", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "");
std::string res = fold.result();
if (res != "") {
path = res;
strcpy(strPath, path.c_str());
pathChanged = true;
}
if (res != "") {
path = res;
strcpy(strPath, path.c_str());
pathChanged = true;
}
pathValid = std::filesystem::is_directory(expandString(path));
dialogOpen = false;
pathValid = std::filesystem::is_directory(expandString(path));
dialogOpen = false;
}

View File

@ -15,13 +15,11 @@ bool isInArea(ImVec2 val, ImVec2 min, ImVec2 max) {
}
FrequencySelect::FrequencySelect() {
}
void FrequencySelect::init() {
for (int i = 0; i < 12; i++) {
digits[i] = 0;
}
}
@ -45,7 +43,6 @@ void FrequencySelect::onPosChange() {
}
void FrequencySelect::onResize() {
}
void FrequencySelect::incrementDigit(int i) {
@ -135,11 +132,11 @@ void FrequencySelect::draw() {
}
sprintf(buf, "%d", digits[i]);
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset, widgetPos.y),
zeros ? disabledColor : textColor, buf);
zeros ? disabledColor : textColor, buf);
if ((i + 1) % 3 == 0 && i < 11) {
commaOffset += commaSz.x;
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + 11, widgetPos.y),
zeros ? disabledColor : textColor, ".");
zeros ? disabledColor : textColor, ".");
}
}

View File

@ -30,7 +30,7 @@ namespace ImGui {
float height = roundf((width / (float)_width) * (float)_height);
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), height);
ImRect bb(min, ImVec2(min.x+size.x, min.y+size.y));
ImRect bb(min, ImVec2(min.x + size.x, min.y + size.y));
float lineHeight = size.y;
ItemSize(size, style.FramePadding.y);

View File

@ -28,6 +28,5 @@ namespace ImGui {
GLuint textureId;
bool newData = false;
};
}

View File

@ -23,7 +23,7 @@ namespace ImGui {
float height = roundf((width / (float)_frameWidth) * (float)_lineCount);
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), height);
ImRect bb(min, ImVec2(min.x+size.x, min.y+size.y));
ImRect bb(min, ImVec2(min.x + size.x, min.y + size.y));
float lineHeight = size.y;
// If there are no lines, there is no point in drawing anything

View File

@ -37,7 +37,5 @@ namespace ImGui {
GLuint textureId;
bool newData = false;
};
}

View File

@ -4,7 +4,6 @@
#include <gui/style.h>
Menu::Menu() {
}
void Menu::registerEntry(std::string name, void (*drawHandler)(void* ctx), void* ctx, ModuleManager::Instance* inst) {
@ -79,8 +78,8 @@ bool Menu::draw(bool updateStates) {
ImVec2 posMin = ImGui::GetCursorScreenPos();
ImVec2 posMax = ImVec2(posMin.x + menuWidth, posMin.y + ImGui::GetFrameHeight());
headerTops[displayedCount-1] = posMin.y;
optionIDs[displayedCount-1] = rawId-1;
headerTops[displayedCount - 1] = posMin.y;
optionIDs[displayedCount - 1] = rawId - 1;
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && ImGui::IsMouseHoveringRect(posMin, posMax)) {
menuClicked = true;
@ -89,7 +88,7 @@ bool Menu::draw(bool updateStates) {
if (menuClicked && ImGui::IsMouseDragging(ImGuiMouseButton_Left) && draggedMenuName.empty() && clickedMenuName == opt.name) {
draggedMenuName = opt.name;
draggedId = rawId-1;
draggedId = rawId - 1;
draggedOpt = opt;
continue;
}

View File

@ -4,7 +4,7 @@
#include <map>
#include <module.h>
#define MAX_MENU_COUNT 1024
#define MAX_MENU_COUNT 1024
class Menu {
public:

View File

@ -39,7 +39,7 @@ namespace ImGui {
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), text);
sprintf(buf, "%d", i * 10);
ImVec2 sz = ImGui::CalcTextSize(buf);
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x/2.0)) + 1, 16), text, buf);
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x / 2.0)) + 1, 16), text, buf);
}
}
}

View File

@ -13,8 +13,8 @@ namespace ImGui {
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), display_format, *v);
// Map from [v_min,v_max] to [0,N]
const int countValues = int((v_max-v_min)/v_step);
int v_i = int((*v - v_min)/v_step);
const int countValues = int((v_max - v_min) / v_step);
int v_i = int((*v - v_min) / v_step);
bool value_changed = ImGui::SliderInt(label, &v_i, 0, countValues, text_buf);
// Remap from [0,N] to [v_min,v_max]

View File

@ -21,7 +21,7 @@ namespace ImGui {
float pad = style.FramePadding.y;
ImVec2 min = window->DC.CursorPos;
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), 100);
ImRect bb(min, ImVec2(min.x+size.x, min.y+size.y));
ImRect bb(min, ImVec2(min.x + size.x, min.y + size.y));
float lineHeight = size.y;
ItemSize(size, style.FramePadding.y);
@ -29,20 +29,20 @@ namespace ImGui {
return;
}
window->DrawList->AddRectFilled(min, ImVec2(min.x+size.x, min.y+size.y), IM_COL32(0,0,0,255));
window->DrawList->AddRectFilled(min, ImVec2(min.x + size.x, min.y + size.y), IM_COL32(0, 0, 0, 255));
ImU32 col = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
ImU32 col2 = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
float increment = size.x / (float)sampleCount;
float val;
for (auto l : lines) {
window->DrawList->AddLine(ImVec2(min.x, (((l * _scale) + 1) * (size.y*0.5f)) + min.y), ImVec2(min.x + size.x, (((l * _scale) + 1) * (size.y*0.5f)) + min.y), IM_COL32(80, 80, 80, 255));
window->DrawList->AddLine(ImVec2(min.x, (((l * _scale) + 1) * (size.y * 0.5f)) + min.y), ImVec2(min.x + size.x, (((l * _scale) + 1) * (size.y * 0.5f)) + min.y), IM_COL32(80, 80, 80, 255));
}
for (int i = 0; i < sampleCount; i++) {
val = buffer[i] * _scale;
if (val > 1.0f || val < -1.0f) { continue; }
window->DrawList->AddCircleFilled(ImVec2(((float)i * increment) + min.x, ((val + 1) * (size.y*0.5f)) + min.y), 2, col);
window->DrawList->AddCircleFilled(ImVec2(((float)i * increment) + min.x, ((val + 1) * (size.y * 0.5f)) + min.y), 2, col);
}
}

View File

@ -25,6 +25,5 @@ namespace ImGui {
float* buffer;
float _scale;
int sampleCount = 0;
};
}

View File

@ -29,25 +29,25 @@ namespace ImGui {
float zeroDb = roundf(((-val_min) / (val_max - val_min)) * size.x);
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32( 9, 136, 9, 255 ));
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(size.x, lineHeight), IM_COL32( 136, 9, 9, 255 ));
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32(9, 136, 9, 255));
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(size.x, lineHeight), IM_COL32(136, 9, 9, 255));
float end = roundf(((avg - val_min) / (val_max - val_min)) * size.x);
float endP = roundf(((peak - val_min) / (val_max - val_min)) * size.x);
if (avg <= 0) {
window->DrawList->AddRectFilled(min, min + ImVec2(end, lineHeight), IM_COL32( 0, 255, 0, 255 ));
window->DrawList->AddRectFilled(min, min + ImVec2(end, lineHeight), IM_COL32(0, 255, 0, 255));
}
else {
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32( 0, 255, 0, 255 ));
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(end, lineHeight), IM_COL32( 255, 0, 0, 255 ));
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32(0, 255, 0, 255));
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(end, lineHeight), IM_COL32(255, 0, 0, 255));
}
if (peak <= 0) {
window->DrawList->AddLine(min + ImVec2(endP, -1), min + ImVec2(endP, lineHeight - 1), IM_COL32( 127, 255, 127, 255 ));
window->DrawList->AddLine(min + ImVec2(endP, -1), min + ImVec2(endP, lineHeight - 1), IM_COL32(127, 255, 127, 255));
}
else {
window->DrawList->AddLine(min + ImVec2(endP, -1), min + ImVec2(endP, lineHeight - 1), IM_COL32( 255, 127, 127, 255 ));
window->DrawList->AddLine(min + ImVec2(endP, -1), min + ImVec2(endP, lineHeight - 1), IM_COL32(255, 127, 127, 255));
}
}
}

View File

@ -10,32 +10,32 @@
#include <gui/gui.h>
float DEFAULT_COLOR_MAP[][3] = {
{0x00, 0x00, 0x20},
{0x00, 0x00, 0x30},
{0x00, 0x00, 0x50},
{0x00, 0x00, 0x91},
{0x1E, 0x90, 0xFF},
{0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0x00},
{0xFE, 0x6D, 0x16},
{0xFF, 0x00, 0x00},
{0xC6, 0x00, 0x00},
{0x9F, 0x00, 0x00},
{0x75, 0x00, 0x00},
{0x4A, 0x00, 0x00}
{ 0x00, 0x00, 0x20 },
{ 0x00, 0x00, 0x30 },
{ 0x00, 0x00, 0x50 },
{ 0x00, 0x00, 0x91 },
{ 0x1E, 0x90, 0xFF },
{ 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0x00 },
{ 0xFE, 0x6D, 0x16 },
{ 0xFF, 0x00, 0x00 },
{ 0xC6, 0x00, 0x00 },
{ 0x9F, 0x00, 0x00 },
{ 0x75, 0x00, 0x00 },
{ 0x4A, 0x00, 0x00 }
};
// TODO: Fix this hacky BS
double freq_ranges[] = {
1.0, 2.0, 2.5, 5.0,
10.0, 20.0, 25.0, 50.0,
100.0, 200.0, 250.0, 500.0,
1000.0, 2000.0, 2500.0, 5000.0,
10000.0, 20000.0, 25000.0, 50000.0,
100000.0, 200000.0, 250000.0, 500000.0,
1000000.0, 2000000.0, 2500000.0, 5000000.0,
10000000.0, 20000000.0, 25000000.0, 50000000.0
1.0, 2.0, 2.5, 5.0,
10.0, 20.0, 25.0, 50.0,
100.0, 200.0, 250.0, 500.0,
1000.0, 2000.0, 2500.0, 5000.0,
10000.0, 20000.0, 25000.0, 50000.0,
100000.0, 200000.0, 250000.0, 500000.0,
1000000.0, 2000000.0, 2500000.0, 5000000.0,
10000000.0, 20000000.0, 25000000.0, 50000000.0
};
inline double findBestRange(double bandwidth, int maxSteps) {
@ -105,8 +105,8 @@ namespace ImGui {
for (float line = startLine; line > fftMin; line -= vRange) {
float yPos = widgetPos.y + fftHeight + 10 - ((line - fftMin) * scaleFactor);
window->DrawList->AddLine(ImVec2(roundf(widgetPos.x + 50), roundf(yPos)),
ImVec2(roundf(widgetPos.x + dataWidth + 50), roundf(yPos)),
IM_COL32(50, 50, 50, 255), 1.0);
ImVec2(roundf(widgetPos.x + dataWidth + 50), roundf(yPos)),
IM_COL32(50, 50, 50, 255), 1.0);
sprintf(buf, "%d", (int)line);
ImVec2 txtSz = ImGui::CalcTextSize(buf);
window->DrawList->AddText(ImVec2(widgetPos.x + 40 - txtSz.x, roundf(yPos - (txtSz.y / 2.0))), text, buf);
@ -118,11 +118,11 @@ namespace ImGui {
for (double freq = startFreq; freq < upperFreq; freq += range) {
double xPos = widgetPos.x + 50 + ((freq - lowerFreq) * horizScale);
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + 10),
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
IM_COL32(50, 50, 50, 255), 1.0);
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
IM_COL32(50, 50, 50, 255), 1.0);
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
text, 1.0);
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
text, 1.0);
printAndScale(freq, buf);
ImVec2 txtSz = ImGui::CalcTextSize(buf);
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), widgetPos.y + fftHeight + 10 + txtSz.y), text, buf);
@ -130,15 +130,15 @@ namespace ImGui {
// Data
if (latestFFT != NULL && fftLines != 0) {
for (int i = 1; i < dataWidth; i++) {
for (int i = 1; i < dataWidth; i++) {
double aPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i - 1] - fftMin) * scaleFactor);
double bPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i] - fftMin) * scaleFactor);
aPos = std::clamp<double>(aPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
bPos = std::clamp<double>(bPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
window->DrawList->AddLine(ImVec2(widgetPos.x + 49 + i, roundf(aPos)),
ImVec2(widgetPos.x + 50 + i, roundf(bPos)), trace, 1.0);
ImVec2(widgetPos.x + 50 + i, roundf(bPos)), trace, 1.0);
window->DrawList->AddLine(ImVec2(widgetPos.x + 50 + i, roundf(bPos)),
ImVec2(widgetPos.x + 50 + i, widgetPos.y + fftHeight + 10), shadow, 1.0);
ImVec2(widgetPos.x + 50 + i, widgetPos.y + fftHeight + 10), shadow, 1.0);
}
}
@ -154,12 +154,12 @@ namespace ImGui {
// X Axis
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10),
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
text, 1.0);
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
text, 1.0);
// Y Axis
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9),
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
text, 1.0);
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
text, 1.0);
}
void WaterFall::drawWaterfall() {
@ -211,7 +211,7 @@ namespace ImGui {
bool mouseHovered, mouseHeld;
bool mouseClicked = ImGui::ButtonBehavior(ImRect(fftAreaMin, wfMax), GetID("WaterfallID"), &mouseHovered, &mouseHeld,
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_PressedOnClick);
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_PressedOnClick);
mouseInFFTResize = (dragOrigin.x > widgetPos.x && dragOrigin.x < widgetPos.x + widgetSize.x && dragOrigin.y >= widgetPos.y + newFFTAreaHeight - 2 && dragOrigin.y <= widgetPos.y + newFFTAreaHeight + 2);
mouseInFreq = IS_IN_AREA(dragOrigin, freqAreaMin, freqAreaMax);
@ -268,11 +268,15 @@ namespace ImGui {
bool resizing = false;
if (_vfo->reference != REF_LOWER) {
if (IS_IN_AREA(mousePos, _vfo->lbwSelMin, _vfo->lbwSelMax)) { resizing = true; }
else if (IS_IN_AREA(mousePos, _vfo->wfLbwSelMin, _vfo->wfLbwSelMax)) { resizing = true; }
else if (IS_IN_AREA(mousePos, _vfo->wfLbwSelMin, _vfo->wfLbwSelMax)) {
resizing = true;
}
}
if (_vfo->reference != REF_UPPER) {
if (IS_IN_AREA(mousePos, _vfo->rbwSelMin, _vfo->rbwSelMax)) { resizing = true; }
else if (IS_IN_AREA(mousePos, _vfo->wfRbwSelMin, _vfo->wfRbwSelMax)) { resizing = true; }
else if (IS_IN_AREA(mousePos, _vfo->wfRbwSelMin, _vfo->wfRbwSelMax)) {
resizing = true;
}
}
if (!resizing) { continue; }
relatedVfo = _vfo;
@ -386,7 +390,7 @@ namespace ImGui {
// If the left and right keys are pressed while hovering the freq scale, move it too
bool leftKeyPressed = ImGui::IsKeyPressed(GLFW_KEY_LEFT);
if ((leftKeyPressed || ImGui::IsKeyPressed(GLFW_KEY_RIGHT)) && mouseInFreq) {
viewOffset += leftKeyPressed ? (viewBandwidth / 20.0) : (-viewBandwidth / 20.0);
viewOffset += leftKeyPressed ? (viewBandwidth / 20.0) : (-viewBandwidth / 20.0);
if (viewOffset + (viewBandwidth / 2.0) > wholeBandwidth / 2.0) {
double freqOffset = (viewOffset + (viewBandwidth / 2.0)) - (wholeBandwidth / 2.0);
@ -412,7 +416,7 @@ namespace ImGui {
}
// Finally, if nothing else was selected, just move the VFO
if ((VFOMoveSingleClick ? ImGui::IsMouseClicked(ImGuiMouseButton_Left) : ImGui::IsMouseDown(ImGuiMouseButton_Left)) && (mouseInFFT|mouseInWaterfall) && (mouseMoved || hoveredVFOName == "")) {
if ((VFOMoveSingleClick ? ImGui::IsMouseClicked(ImGuiMouseButton_Left) : ImGui::IsMouseDown(ImGuiMouseButton_Left)) && (mouseInFFT | mouseInWaterfall) && (mouseMoved || hoveredVFOName == "")) {
if (selVfo != NULL) {
int refCenter = mousePos.x - (widgetPos.x + 50);
if (refCenter >= 0 && refCenter < dataWidth) {
@ -509,13 +513,13 @@ namespace ImGui {
// Calculate FFT index data
double vfoMinSizeFreq = _vfo->centerOffset - _vfo->bandwidth;
double vfoMinFreq = _vfo->centerOffset - (_vfo->bandwidth/2.0);
double vfoMaxFreq = _vfo->centerOffset + (_vfo->bandwidth/2.0);
double vfoMinFreq = _vfo->centerOffset - (_vfo->bandwidth / 2.0);
double vfoMaxFreq = _vfo->centerOffset + (_vfo->bandwidth / 2.0);
double vfoMaxSizeFreq = _vfo->centerOffset + _vfo->bandwidth;
int vfoMinSideOffset = std::clamp<int>(((vfoMinSizeFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
int vfoMinOffset = std::clamp<int>(((vfoMinFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
int vfoMaxOffset = std::clamp<int>(((vfoMaxFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
int vfoMaxSideOffset = std::clamp<int>(((vfoMaxSizeFreq / (wholeBandwidth/2.0)) * (double)(rawFFTSize/2)) + (rawFFTSize/2), 0, rawFFTSize);
int vfoMinSideOffset = std::clamp<int>(((vfoMinSizeFreq / (wholeBandwidth / 2.0)) * (double)(rawFFTSize / 2)) + (rawFFTSize / 2), 0, rawFFTSize);
int vfoMinOffset = std::clamp<int>(((vfoMinFreq / (wholeBandwidth / 2.0)) * (double)(rawFFTSize / 2)) + (rawFFTSize / 2), 0, rawFFTSize);
int vfoMaxOffset = std::clamp<int>(((vfoMaxFreq / (wholeBandwidth / 2.0)) * (double)(rawFFTSize / 2)) + (rawFFTSize / 2), 0, rawFFTSize);
int vfoMaxSideOffset = std::clamp<int>(((vfoMaxSizeFreq / (wholeBandwidth / 2.0)) * (double)(rawFFTSize / 2)) + (rawFFTSize / 2), 0, rawFFTSize);
double avg = 0;
float max = -INFINITY;
@ -638,19 +642,19 @@ namespace ImGui {
}
if (width >= 1.0) {
window->DrawList->AddRectFilled(ImVec2(roundf(aPos), bpBottom - height),
ImVec2(roundf(bPos), bpBottom), colorTrans);
ImVec2(roundf(bPos), bpBottom), colorTrans);
if (startVis) {
window->DrawList->AddLine(ImVec2(roundf(aPos), bpBottom - height - 1),
ImVec2(roundf(aPos), bpBottom - 1), color);
ImVec2(roundf(aPos), bpBottom - 1), color);
}
if (endVis) {
window->DrawList->AddLine(ImVec2(roundf(bPos), bpBottom - height - 1),
ImVec2(roundf(bPos), bpBottom - 1), color);
ImVec2(roundf(bPos), bpBottom - 1), color);
}
}
if (txtSz.x <= width) {
window->DrawList->AddText(ImVec2(cPos - (txtSz.x / 2.0), bpBottom - (height / 2.0f) - (txtSz.y / 2.0f)),
IM_COL32(255, 255, 255, 255), bandplan->bands[i].name.c_str());
IM_COL32(255, 255, 255, 255), bandplan->bands[i].name.c_str());
}
}
}
@ -682,7 +686,7 @@ namespace ImGui {
waterfallHeight = widgetSize.y - fftHeight - 52;
}
else {
fftHeight = widgetSize.y - 50;
fftHeight = widgetSize.y - 50;
}
dataWidth = widgetSize.x - 60.0;
@ -766,7 +770,7 @@ namespace ImGui {
//window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
ImU32 bg = ImGui::ColorConvertFloat4ToU32(gui::themeManager.waterfallBg);
window->DrawList->AddRectFilled(widgetPos, widgetEndPos, bg);
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32( 50, 50, 50, 255 ));
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32(50, 50, 50, 255));
window->DrawList->AddLine(ImVec2(widgetPos.x, widgetPos.y + fftHeight + 50), ImVec2(widgetPos.x + widgetSize.x, widgetPos.y + fftHeight + 50), IM_COL32(50, 50, 50, 255), 1.0);
if (!gui::mainWindow.lockWaterfallControls) {
@ -1138,7 +1142,6 @@ namespace ImGui {
}
reference = ref;
setOffset(generalOffset);
}
void WaterfallVFO::updateDrawingVars(double viewBandwidth, float dataWidth, double viewOffset, ImVec2 widgetPos, int fftHeight) {
@ -1202,18 +1205,22 @@ namespace ImGui {
if (rectMax.x - rectMin.x < 10) { return; }
if (reference != REF_LOWER && !bandwidthLocked && !leftClamped) {
if (IS_IN_AREA(mousePos, lbwSelMin, lbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
else if (IS_IN_AREA(mousePos, wfLbwSelMin, wfLbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
else if (IS_IN_AREA(mousePos, wfLbwSelMin, wfLbwSelMax)) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
}
}
if (reference != REF_UPPER && !bandwidthLocked && !rightClamped) {
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
}
}
}
};
void WaterFall::showWaterfall() {
buf_mtx.lock();
if (rawFFTs == NULL) {
if (rawFFTs == NULL) {
spdlog::error("Null rawFFT");
}
waterfallVisible = true;
@ -1254,4 +1261,3 @@ namespace ImGui {
snapInterval = interval;
}
};

View File

@ -7,7 +7,7 @@
#include <GL/glew.h>
#include <utils/event.h>
#define WATERFALL_RESOLUTION 1000000
#define WATERFALL_RESOLUTION 1000000
namespace ImGui {
class WaterfallVFO {
@ -270,9 +270,9 @@ namespace ImGui {
int maxVSteps;
int maxHSteps;
int dataWidth; // Width of the FFT and waterfall
int fftHeight; // Height of the fft graph
int waterfallHeight = 0; // Height of the waterfall
int dataWidth; // Width of the FFT and waterfall
int fftHeight; // Height of the fft graph
int waterfallHeight = 0; // Height of the waterfall
double viewBandwidth;
double viewOffset;

View File

@ -22,10 +22,10 @@ ModuleManager::Module_t ModuleManager::loadModule(std::string path) {
return mod;
}
mod.info = (ModuleInfo_t*)GetProcAddress(mod.handle, "_INFO_");
mod.init = (void(*)())GetProcAddress(mod.handle, "_INIT_");
mod.createInstance = (Instance*(*)(std::string))GetProcAddress(mod.handle, "_CREATE_INSTANCE_");
mod.deleteInstance = (void(*)(Instance*))GetProcAddress(mod.handle, "_DELETE_INSTANCE_");
mod.end = (void(*)())GetProcAddress(mod.handle, "_END_");
mod.init = (void (*)())GetProcAddress(mod.handle, "_INIT_");
mod.createInstance = (Instance * (*)(std::string)) GetProcAddress(mod.handle, "_CREATE_INSTANCE_");
mod.deleteInstance = (void (*)(Instance*))GetProcAddress(mod.handle, "_DELETE_INSTANCE_");
mod.end = (void (*)())GetProcAddress(mod.handle, "_END_");
#else
mod.handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
if (mod.handle == NULL) {
@ -34,10 +34,10 @@ ModuleManager::Module_t ModuleManager::loadModule(std::string path) {
return mod;
}
mod.info = (ModuleInfo_t*)dlsym(mod.handle, "_INFO_");
mod.init = (void(*)())dlsym(mod.handle, "_INIT_");
mod.createInstance = (Instance*(*)(std::string))dlsym(mod.handle, "_CREATE_INSTANCE_");
mod.deleteInstance = (void(*)(Instance*))dlsym(mod.handle, "_DELETE_INSTANCE_");
mod.end = (void(*)())dlsym(mod.handle, "_END_");
mod.init = (void (*)())dlsym(mod.handle, "_INIT_");
mod.createInstance = (Instance * (*)(std::string)) dlsym(mod.handle, "_CREATE_INSTANCE_");
mod.deleteInstance = (void (*)(Instance*))dlsym(mod.handle, "_DELETE_INSTANCE_");
mod.end = (void (*)())dlsym(mod.handle, "_END_");
#endif
if (mod.info == NULL) {
spdlog::error("{0} is missing _INFO_ symbol", path);
@ -107,7 +107,7 @@ int ModuleManager::deleteInstance(std::string name) {
return -1;
}
onInstanceDelete.emit(name);
Instance_t inst = instances[name];
Instance_t inst = instances[name];
inst.module.deleteInstance(inst.instance);
instances.erase(name);
onInstanceDeleted.emit(name);

View File

@ -15,17 +15,17 @@
#endif
#ifdef _WIN32
#include <Windows.h>
#define MOD_EXPORT extern "C" __declspec(dllexport)
#define SDRPP_MOD_EXTENTSION ".dll"
#include <Windows.h>
#define MOD_EXPORT extern "C" __declspec(dllexport)
#define SDRPP_MOD_EXTENTSION ".dll"
#else
#include <dlfcn.h>
#define MOD_EXPORT extern "C"
#ifdef __APPLE__
#define SDRPP_MOD_EXTENTSION ".dylib"
#else
#define SDRPP_MOD_EXTENTSION ".so"
#endif
#include <dlfcn.h>
#define MOD_EXPORT extern "C"
#ifdef __APPLE__
#define SDRPP_MOD_EXTENTSION ".dylib"
#else
#define SDRPP_MOD_EXTENTSION ".so"
#endif
#endif
class ModuleManager {
@ -98,7 +98,6 @@ public:
std::map<std::string, ModuleManager::Module_t> modules;
std::map<std::string, ModuleManager::Instance_t> instances;
};
#define SDRPP_MOD_INFO MOD_EXPORT const ModuleManager::ModuleInfo_t _INFO_
#define SDRPP_MOD_INFO MOD_EXPORT const ModuleManager::ModuleInfo_t _INFO_

View File

@ -18,7 +18,7 @@ namespace options {
#endif
}
bool parse(int argc, char *argv[]) {
bool parse(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
char* arg = argv[i];
if (!strcmp(arg, "-r") || !strcmp(arg, "--root")) {

View File

@ -12,5 +12,5 @@ namespace options {
SDRPP_EXPORT CMDLineOptions opts;
void loadDefaults();
bool parse(int argc, char *argv[]);
bool parse(int argc, char* argv[]);
}

View File

@ -2,10 +2,9 @@
#include <core.h>
SignalPath::SignalPath() {
}
void SignalPath::init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream<dsp::complex_t>* input, dsp::complex_t* fftBuffer, void fftHandler(dsp::complex_t*,int,void*), void* fftHandlerCtx) {
void SignalPath::init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream<dsp::complex_t>* input, dsp::complex_t* fftBuffer, void fftHandler(dsp::complex_t*, int, void*), void* fftHandlerCtx) {
this->sampleRate = sampleRate;
this->sourceSampleRate = sampleRate;
this->fftRate = fftRate;
@ -195,13 +194,13 @@ void SignalPath::setDecimation(int dec) {
decimator = new dsp::HalfDecimator<dsp::complex_t>(&inputBuffer.out, &halfBandWindow);
}
else {
decimator = new dsp::HalfDecimator<dsp::complex_t>(&decimators[i-1]->out, &halfBandWindow);
decimator = new dsp::HalfDecimator<dsp::complex_t>(&decimators[i - 1]->out, &halfBandWindow);
}
if (running) { decimator->start(); }
decimators.push_back(decimator);
}
split.setInput(&decimators[decimators.size()-1]->out);
split.setInput(&decimators[decimators.size() - 1]->out);
if (running) { split.start(); }
// Update the DSP sample rate
@ -247,12 +246,12 @@ void SignalPath::setFFTWindow(int win) {
void SignalPath::generateFFTWindow(int win, float* taps, int size) {
if (win == FFT_WINDOW_RECTANGULAR) {
for (int i = 0; i < size; i++) {
taps[i] = (i%2) ? 1 : -1;
taps[i] = (i % 2) ? 1 : -1;
}
}
else if (win == FFT_WINDOW_BLACKMAN) {
for (int i = 0; i < size; i++) {
taps[i] = ((i%2) ? dsp::window_function::blackman(i, size) : -dsp::window_function::blackman(i, size))*2;
taps[i] = ((i % 2) ? dsp::window_function::blackman(i, size) : -dsp::window_function::blackman(i, size)) * 2;
}
}
}

View File

@ -15,7 +15,7 @@ enum {
class SignalPath {
public:
SignalPath();
void init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream<dsp::complex_t>* input, dsp::complex_t* fftBuffer, void fftHandler(dsp::complex_t*,int,void*), void* fftHandlerCtx);
void init(uint64_t sampleRate, int fftRate, int fftSize, dsp::stream<dsp::complex_t>* input, dsp::complex_t* fftBuffer, void fftHandler(dsp::complex_t*, int, void*), void* fftHandlerCtx);
void start();
void stop();
void setSampleRate(double sampleRate);

View File

@ -86,7 +86,6 @@ public:
private:
dsp::NullSink<dsp::stereo_t> ns;
};
void registerSinkProvider(std::string name, SinkProvider provider);
@ -130,5 +129,4 @@ private:
std::vector<std::string> providerNames;
std::string providerNamesTxt;
std::vector<std::string> streamNames;
};

View File

@ -3,7 +3,6 @@
#include <signal_path/signal_path.h>
SourceManager::SourceManager() {
}
void SourceManager::registerSource(std::string name, SourceHandler* handler) {
@ -34,11 +33,11 @@ void SourceManager::unregisterSource(std::string name) {
std::vector<std::string> SourceManager::getSourceNames() {
std::vector<std::string> names;
for (auto const& [name, src] : sources) { names.push_back(name); }
for (auto const& [name, src] : sources) { names.push_back(name); }
return names;
}
void SourceManager::selectSource(std::string name) {
void SourceManager::selectSource(std::string name) {
if (sources.find(name) == sources.end()) {
spdlog::error("Tried to select non existent source: {0}", name);
return;

View File

@ -23,7 +23,7 @@ public:
void registerSource(std::string name, SourceHandler* handler);
void unregisterSource(std::string name);
void selectSource(std::string name);
void selectSource(std::string name);
void showSelectedMenu();
void start();
void stop();
@ -43,5 +43,4 @@ private:
double tuneOffset;
double currentFreq;
dsp::stream<dsp::complex_t> nullSource;
};

View File

@ -87,7 +87,6 @@ std::string VFOManager::VFO::getName() {
}
VFOManager::VFOManager() {
}
VFOManager::VFO* VFOManager::createVFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked) {
@ -187,7 +186,7 @@ int VFOManager::getReference(std::string name) {
return vfos[name]->getReference();
}
void VFOManager::setColor(std::string name, ImU32 color) {
void VFOManager::setColor(std::string name, ImU32 color) {
if (vfos.find(name) == vfos.end()) {
return;
}

View File

@ -35,7 +35,6 @@ public:
private:
std::string name;
};
VFOManager::VFO* createVFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked);

View File

@ -11,9 +11,15 @@ namespace color {
// Calculate the hue
if (delta == 0) { h = 0; }
else if (r > g && r > b) { h = 60.0f * fmodf((g - b) / delta, 6.0f); }
else if (g > r && g > b) { h = 60.0f * (((b - r) / delta) + 2.0f); }
else { h = 60.0f * (((r - g) / delta) + 4.0f); }
else if (r > g && r > b) {
h = 60.0f * fmodf((g - b) / delta, 6.0f);
}
else if (g > r && g > b) {
h = 60.0f * (((b - r) / delta) + 2.0f);
}
else {
h = 60.0f * (((r - g) / delta) + 4.0f);
}
// Calculate lightness
l = (cmin + cmax) / 2.0f;
@ -29,12 +35,36 @@ namespace color {
float m = l - (c / 2.0f);
// Affect coefficients to R, G or B depending on hue
if (h < 60) { r = c; g = x; b = 0; }
else if (h < 120) { r = x; g = c; b = 0; }
else if (h < 180) { r = 0; g = c; b = x; }
else if (h < 240) { r = 0; g = x; b = c; }
else if (h < 300) { r = x; g = 0; b = c; }
else { r = c; g = 0; b = x; }
if (h < 60) {
r = c;
g = x;
b = 0;
}
else if (h < 120) {
r = x;
g = c;
b = 0;
}
else if (h < 180) {
r = 0;
g = c;
b = x;
}
else if (h < 240) {
r = 0;
g = x;
b = c;
}
else if (h < 300) {
r = x;
g = 0;
b = c;
}
else {
r = c;
g = 0;
b = x;
}
// Add m
r += m;

View File

@ -40,5 +40,4 @@ public:
private:
std::vector<EventHandler<T>*> handlers;
};

View File

@ -9,7 +9,10 @@ namespace utils {
int len = strlen(str) - 1;
while ((str[len] == '0' || str[len] == '.') && len > 0) {
len--;
if (str[len] == '.') { len--; break; }
if (str[len] == '.') {
len--;
break;
}
}
return std::string(str).substr(0, len + 1) + "MHz";
}
@ -18,7 +21,10 @@ namespace utils {
int len = strlen(str) - 1;
while ((str[len] == '0' || str[len] == '.') && len > 0) {
len--;
if (str[len] == '.') { len--; break; }
if (str[len] == '.') {
len--;
break;
}
}
return std::string(str).substr(0, len + 1) + "KHz";
}
@ -27,7 +33,10 @@ namespace utils {
int len = strlen(str) - 1;
while ((str[len] == '0' || str[len] == '.') && len > 0) {
len--;
if (str[len] == '.') { len--; break; }
if (str[len] == '.') {
len--;
break;
}
}
return std::string(str).substr(0, len + 1) + "Hz";
}

View File

@ -59,7 +59,7 @@ namespace net {
void ConnClass::waitForEnd() {
std::unique_lock lck(readQueueMtx);
connectionOpenCnd.wait(lck, [this](){ return !connectionOpen; });
connectionOpenCnd.wait(lck, [this]() { return !connectionOpen; });
}
int ConnClass::read(int count, uint8_t* buf) {
@ -148,7 +148,7 @@ namespace net {
while (true) {
// Wait for wakeup and exit if it's for terminating the thread
std::unique_lock lck(readQueueMtx);
readQueueCnd.wait(lck, [this](){ return (readQueue.size() > 0 || stopWorkers); });
readQueueCnd.wait(lck, [this]() { return (readQueue.size() > 0 || stopWorkers); });
if (stopWorkers || !connectionOpen) { return; }
// Pop first element off the list
@ -174,7 +174,7 @@ namespace net {
while (true) {
// Wait for wakeup and exit if it's for terminating the thread
std::unique_lock lck(writeQueueMtx);
writeQueueCnd.wait(lck, [this](){ return (writeQueue.size() > 0 || stopWorkers); });
writeQueueCnd.wait(lck, [this]() { return (writeQueue.size() > 0 || stopWorkers); });
if (stopWorkers || !connectionOpen) { return; }
// Pop first element off the list
@ -261,7 +261,6 @@ namespace net {
if (acceptWorkerThread.joinable()) { acceptWorkerThread.join(); }
listening = false;
}
@ -273,7 +272,7 @@ namespace net {
while (true) {
// Wait for wakeup and exit if it's for terminating the thread
std::unique_lock lck(acceptQueueMtx);
acceptQueueCnd.wait(lck, [this](){ return (acceptQueue.size() > 0 || stopWorker); });
acceptQueueCnd.wait(lck, [this]() { return (acceptQueue.size() > 0 || stopWorker); });
if (stopWorker || !listening) { return; }
// Pop first element off the list
@ -299,13 +298,13 @@ namespace net {
Conn connect(std::string host, uint16_t port) {
Socket sock;
Socket sock;
#ifdef _WIN32
// Initialize WinSock2
if (!winsock_init) {
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2),&wsa)) {
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
throw std::runtime_error("Could not initialize WinSock2");
return NULL;
}
@ -335,7 +334,7 @@ namespace net {
struct sockaddr_in addr;
addr.sin_addr.s_addr = *naddr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_port = htons(port);
// Connect to host
if (::connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
@ -353,7 +352,7 @@ namespace net {
// Initialize WinSock2
if (!winsock_init) {
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2),&wsa)) {
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
throw std::runtime_error("Could not initialize WinSock2");
return NULL;
}
@ -377,7 +376,7 @@ namespace net {
// This option has a different meaning on Windows,
// so we use it only for non-Windows systems
int enable = 1;
if (setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof (int)) < 0) {
if (setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) {
throw std::runtime_error("Could not configure socket");
return NULL;
}
@ -395,7 +394,7 @@ namespace net {
struct sockaddr_in addr;
addr.sin_addr.s_addr = *naddr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_port = htons(port);
// Bind socket
if (bind(listenSock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
@ -419,7 +418,7 @@ namespace net {
// Initialize WinSock2
if (!winsock_init) {
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2),&wsa)) {
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
throw std::runtime_error("Could not initialize WinSock2");
return NULL;
}
@ -455,15 +454,15 @@ namespace net {
// Create host address
struct sockaddr_in addr;
addr.sin_addr.s_addr = INADDR_ANY;//*naddr;
addr.sin_addr.s_addr = INADDR_ANY; //*naddr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_port = htons(port);
// Create remote host address
struct sockaddr_in raddr;
raddr.sin_addr.s_addr = *rnaddr;
raddr.sin_family = AF_INET;
raddr.sin_port = htons(remotePort);
raddr.sin_port = htons(remotePort);
// Bind socket
if (bindSocket) {

View File

@ -78,7 +78,6 @@ namespace net {
Socket _sock;
bool _udp;
struct sockaddr_in remoteAddr;
};
typedef std::unique_ptr<ConnClass> Conn;
@ -112,7 +111,6 @@ namespace net {
std::thread acceptWorkerThread;
Socket sock;
};
typedef std::unique_ptr<ListenerClass> Listener;

View File

@ -95,7 +95,7 @@ public:
return values[id];
}
T operator [](int& id) {
T operator[](int& id) {
return value(id);
}
@ -115,5 +115,4 @@ private:
std::vector<std::string> names;
std::vector<T> values;
std::string _txt;
};

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
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[] = {
@ -85,29 +84,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;
@ -122,6 +136,5 @@ namespace dsp {
correct_reed_solomon* rs;
stream<uint8_t>* _in;
};
}

View File

@ -85,8 +85,7 @@ namespace dsp {
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) {
@ -99,7 +98,6 @@ namespace dsp {
memcpy(out.writeBuf, &data[i], length);
out.swap(length);
i += length;
}
_in->flush();
@ -116,6 +114,5 @@ namespace dsp {
uint8_t packet[0x4008];
stream<uint8_t>* _in;
};
}

View File

@ -23,9 +23,9 @@
#include <fstream>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
#define CONCAT(a, b) ((std::string(a) + b).c_str())
SDRPP_MOD_INFO {
SDRPP_MOD_INFO{
/* Name: */ "falcon9_decoder",
/* Description: */ "Falcon9 telemetry decoder for SDR++",
/* Author: */ "Ryzerth",
@ -33,7 +33,7 @@ SDRPP_MOD_INFO {
/* Max instances */ -1
};
#define INPUT_SAMPLE_RATE 6000000
#define INPUT_SAMPLE_RATE 6000000
std::ofstream file("output.ts");
@ -84,7 +84,6 @@ public:
}
~Falcon9DecoderModule() {
}
void postInit() {}
@ -187,8 +186,7 @@ private:
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
uint16_t length = (((data[0] & 0b1111) << 8) | data[1]) + 2;
uint64_t pktId = ((uint64_t)data[2] << 56) | ((uint64_t)data[3] << 48) | ((uint64_t)data[4] << 40) | ((uint64_t)data[5] << 32)
| ((uint64_t)data[6] << 24) | ((uint64_t)data[7] << 16) | ((uint64_t)data[8] << 8) | data[9];
uint64_t pktId = ((uint64_t)data[2] << 56) | ((uint64_t)data[3] << 48) | ((uint64_t)data[4] << 40) | ((uint64_t)data[5] << 32) | ((uint64_t)data[6] << 24) | ((uint64_t)data[7] << 16) | ((uint64_t)data[8] << 8) | data[9];
if (pktId == 0x0117FE0800320303 || pktId == 0x0112FA0800320303) {
data[length - 2] = 0;
@ -207,7 +205,7 @@ private:
static void symSinkHandler(float* data, int count, void* ctx) {
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
float* buf = _this->symDiag.acquireBuffer();
memcpy(buf, data, 1024*sizeof(float));
memcpy(buf, data, 1024 * sizeof(float));
_this->symDiag.releaseBuffer();
}
@ -232,7 +230,7 @@ private:
dsp::stream<float> thrInput;
dsp::Threshold thr;
uint8_t syncWord[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};
uint8_t syncWord[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 };
dsp::Deframer deframe;
dsp::FalconRS falconRS;
dsp::FalconPacketSync pkt;
@ -243,7 +241,6 @@ private:
VFOManager::VFO* vfo;
ImGui::SymbolDiagram symDiag;
};
MOD_EXPORT void _INIT_() {

View File

@ -1,11 +1,11 @@
#include <base40.h>
void decode_callsign_base40(uint64_t encoded, char *callsign) {
void decode_callsign_base40(uint64_t encoded, char* callsign) {
if (encoded >= 262144000000000) { // 40^9
*callsign = 0;
return;
}
char *p = callsign;
char* p = callsign;
for (; encoded > 0; p++) {
*p = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."[encoded % 40];
encoded /= 40;

View File

@ -6,67 +6,57 @@
#include <array>
#include <cstddef>
namespace mobilinkd
{
namespace mobilinkd {
template <uint16_t Poly = 0x5935, uint16_t Init = 0xFFFF>
struct CRC16
{
static constexpr uint16_t MASK = 0xFFFF;
static constexpr uint16_t LSB = 0x0001;
static constexpr uint16_t MSB = 0x8000;
template <uint16_t Poly = 0x5935, uint16_t Init = 0xFFFF>
struct CRC16 {
static constexpr uint16_t MASK = 0xFFFF;
static constexpr uint16_t LSB = 0x0001;
static constexpr uint16_t MSB = 0x8000;
uint16_t reg_ = Init;
uint16_t reg_ = Init;
void reset()
{
reg_ = Init;
void reset() {
reg_ = Init;
for (size_t i = 0; i != 16; ++i)
{
auto bit = reg_ & LSB;
if (bit) reg_ ^= Poly;
reg_ >>= 1;
if (bit) reg_ |= MSB;
for (size_t i = 0; i != 16; ++i) {
auto bit = reg_ & LSB;
if (bit) reg_ ^= Poly;
reg_ >>= 1;
if (bit) reg_ |= MSB;
}
reg_ &= MASK;
}
reg_ &= MASK;
}
void operator()(uint8_t byte)
{
reg_ = crc(byte, reg_);
}
uint16_t crc(uint8_t byte, uint16_t reg)
{
for (size_t i = 0; i != 8; ++i)
{
auto msb = reg & MSB;
reg = ((reg << 1) & MASK) | ((byte >> (7 - i)) & LSB);
if (msb) reg ^= Poly;
void operator()(uint8_t byte) {
reg_ = crc(byte, reg_);
}
return reg & MASK;
}
uint16_t get()
{
auto reg = reg_;
for (size_t i = 0; i != 16; ++i)
{
auto msb = reg & MSB;
reg = ((reg << 1) & MASK);
if (msb) reg ^= Poly;
uint16_t crc(uint8_t byte, uint16_t reg) {
for (size_t i = 0; i != 8; ++i) {
auto msb = reg & MSB;
reg = ((reg << 1) & MASK) | ((byte >> (7 - i)) & LSB);
if (msb) reg ^= Poly;
}
return reg & MASK;
}
return reg;
}
std::array<uint8_t, 2> get_bytes()
{
auto crc = get();
std::array<uint8_t, 2> result{uint8_t((crc >> 8) & 0xFF), uint8_t(crc & 0xFF)};
return result;
}
};
uint16_t get() {
auto reg = reg_;
for (size_t i = 0; i != 16; ++i) {
auto msb = reg & MSB;
reg = ((reg << 1) & MASK);
if (msb) reg ^= Poly;
}
return reg;
}
std::array<uint8_t, 2> get_bytes() {
auto crc = get();
std::array<uint8_t, 2> result{ uint8_t((crc >> 8) & 0xFF), uint8_t(crc & 0xFF) };
return result;
}
};
} // mobilinkd

View File

@ -10,224 +10,194 @@
namespace mobilinkd {
// Parts are adapted from:
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
// Parts are adapted from:
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
namespace Golay24
{
namespace Golay24 {
int popcount(uint32_t n) {
int count = 0;
for (int i = 0; i < 32; i++) {
count += ((n >> i) & 1);
int popcount(uint32_t n) {
int count = 0;
for (int i = 0; i < 32; i++) {
count += ((n >> i) & 1);
}
return count;
}
return count;
}
namespace detail
{
namespace detail {
// Need a constexpr sort.
// https://stackoverflow.com/a/40030044/854133
template<class T>
void swap(T& l, T& r)
{
T tmp = std::move(l);
l = std::move(r);
r = std::move(tmp);
}
// Need a constexpr sort.
// https://stackoverflow.com/a/40030044/854133
template <class T>
void swap(T& l, T& r) {
T tmp = std::move(l);
l = std::move(r);
r = std::move(tmp);
}
template <typename T, size_t N>
struct array
{
constexpr T& operator[](size_t i)
{
return arr[i];
}
template <typename T, size_t N>
struct array {
constexpr T& operator[](size_t i) {
return arr[i];
}
constexpr const T& operator[](size_t i) const
{
return arr[i];
}
constexpr const T& operator[](size_t i) const {
return arr[i];
}
constexpr const T* begin() const
{
return arr;
}
constexpr const T* end() const
{
return arr + N;
}
constexpr const T* begin() const {
return arr;
}
constexpr const T* end() const {
return arr + N;
}
T arr[N];
};
T arr[N];
};
template <typename T, size_t N>
void sort_impl(array<T, N> &array, size_t left, size_t right)
{
if (left < right)
{
size_t m = left;
template <typename T, size_t N>
void sort_impl(array<T, N>& array, size_t left, size_t right) {
if (left < right) {
size_t m = left;
for (size_t i = left + 1; i<right; i++)
if (array[i]<array[left])
swap(array[++m], array[i]);
for (size_t i = left + 1; i < right; i++)
if (array[i] < array[left])
swap(array[++m], array[i]);
swap(array[left], array[m]);
swap(array[left], array[m]);
sort_impl(array, left, m);
sort_impl(array, m + 1, right);
}
}
sort_impl(array, left, m);
sort_impl(array, m + 1, right);
}
}
template <typename T, size_t N>
array<T, N> sort(array<T, N> array)
{
auto sorted = array;
sort_impl(sorted, 0, N);
return sorted;
}
template <typename T, size_t N>
array<T, N> sort(array<T, N> array) {
auto sorted = array;
sort_impl(sorted, 0, N);
return sorted;
}
} // detail
} // detail
// static constexpr uint16_t POLY = 0xAE3;
constexpr uint16_t POLY = 0xC75;
// static constexpr uint16_t POLY = 0xAE3;
constexpr uint16_t POLY = 0xC75;
#pragma pack(push, 1)
struct SyndromeMapEntry
{
uint32_t a{0};
uint16_t b{0};
};
struct SyndromeMapEntry {
uint32_t a{ 0 };
uint16_t b{ 0 };
};
#pragma pack(pop)
/**
/**
* Calculate the syndrome of a [23,12] Golay codeword.
*
* @return the 11-bit syndrome of the codeword in bits [22:12].
*/
uint32_t syndrome(uint32_t codeword)
{
codeword &= 0xffffffl;
for (size_t i = 0; i != 12; ++i)
{
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return (codeword << 12);
}
bool parity(uint32_t codeword)
{
return popcount(codeword) & 1;
}
SyndromeMapEntry makeSyndromeMapEntry(uint64_t val)
{
return SyndromeMapEntry{uint32_t(val >> 16), uint16_t(val & 0xFFFF)};
}
uint64_t makeSME(uint64_t syndrome, uint32_t bits)
{
return (syndrome << 24) | (bits & 0xFFFFFF);
}
constexpr size_t LUT_SIZE = 2048;
std::array<SyndromeMapEntry, LUT_SIZE> make_lut()
{
constexpr size_t VECLEN=23;
detail::array<uint64_t, LUT_SIZE> result{};
size_t index = 0;
result[index++] = makeSME(syndrome(0), 0);
for (size_t i = 0; i != VECLEN; ++i)
{
auto v = (1 << i);
result[index++] = makeSME(syndrome(v), v);
}
for (size_t i = 0; i != VECLEN - 1; ++i)
{
for (size_t j = i + 1; j != VECLEN; ++j)
{
auto v = (1 << i) | (1 << j);
result[index++] = makeSME(syndrome(v), v);
uint32_t syndrome(uint32_t codeword) {
codeword &= 0xffffffl;
for (size_t i = 0; i != 12; ++i) {
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return (codeword << 12);
}
}
for (size_t i = 0; i != VECLEN - 2; ++i)
{
for (size_t j = i + 1; j != VECLEN - 1; ++j)
{
for (size_t k = j + 1; k != VECLEN; ++k)
{
auto v = (1 << i) | (1 << j) | (1 << k);
bool parity(uint32_t codeword) {
return popcount(codeword) & 1;
}
SyndromeMapEntry makeSyndromeMapEntry(uint64_t val) {
return SyndromeMapEntry{ uint32_t(val >> 16), uint16_t(val & 0xFFFF) };
}
uint64_t makeSME(uint64_t syndrome, uint32_t bits) {
return (syndrome << 24) | (bits & 0xFFFFFF);
}
constexpr size_t LUT_SIZE = 2048;
std::array<SyndromeMapEntry, LUT_SIZE> make_lut() {
constexpr size_t VECLEN = 23;
detail::array<uint64_t, LUT_SIZE> result{};
size_t index = 0;
result[index++] = makeSME(syndrome(0), 0);
for (size_t i = 0; i != VECLEN; ++i) {
auto v = (1 << i);
result[index++] = makeSME(syndrome(v), v);
}
for (size_t i = 0; i != VECLEN - 1; ++i) {
for (size_t j = i + 1; j != VECLEN; ++j) {
auto v = (1 << i) | (1 << j);
result[index++] = makeSME(syndrome(v), v);
}
}
for (size_t i = 0; i != VECLEN - 2; ++i) {
for (size_t j = i + 1; j != VECLEN - 1; ++j) {
for (size_t k = j + 1; k != VECLEN; ++k) {
auto v = (1 << i) | (1 << j) | (1 << k);
result[index++] = makeSME(syndrome(v), v);
}
}
}
result = detail::sort(result);
std::array<SyndromeMapEntry, LUT_SIZE> tmp;
for (size_t i = 0; i != LUT_SIZE; ++i) {
tmp[i] = makeSyndromeMapEntry(result[i]);
}
return tmp;
}
}
result = detail::sort(result);
inline auto LUT = make_lut();
std::array<SyndromeMapEntry, LUT_SIZE> tmp;
for (size_t i = 0; i != LUT_SIZE; ++i)
{
tmp[i] = makeSyndromeMapEntry(result[i]);
}
return tmp;
}
inline auto LUT = make_lut();
/**
/**
* Calculate [23,12] Golay codeword.
*
* @return checkbits(11)|data(12).
*/
uint32_t encode23(uint16_t data)
{
// data &= 0xfff;
uint32_t codeword = data;
for (size_t i = 0; i != 12; ++i)
{
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return codeword | (data << 11);
}
uint32_t encode23(uint16_t data) {
// data &= 0xfff;
uint32_t codeword = data;
for (size_t i = 0; i != 12; ++i) {
if (codeword & 1)
codeword ^= POLY;
codeword >>= 1;
}
return codeword | (data << 11);
}
uint32_t encode24(uint16_t data)
{
auto codeword = encode23(data);
return ((codeword << 1) | parity(codeword));
}
uint32_t encode24(uint16_t data) {
auto codeword = encode23(data);
return ((codeword << 1) | parity(codeword));
}
bool decode(uint32_t input, uint32_t& output)
{
auto syndrm = syndrome(input >> 1);
auto it = std::lower_bound(LUT.begin(), LUT.end(), syndrm,
[](const SyndromeMapEntry& sme, uint32_t val){
return (sme.a >> 8) < val;
});
bool decode(uint32_t input, uint32_t& output) {
auto syndrm = syndrome(input >> 1);
auto it = std::lower_bound(LUT.begin(), LUT.end(), syndrm,
[](const SyndromeMapEntry& sme, uint32_t val) {
return (sme.a >> 8) < val;
});
if ((it->a >> 8) == syndrm)
{
// Build the correction from the compressed entry.
auto correction = ((((it->a & 0xFF) << 16) | it->b) << 1);
// Apply the correction to the input.
output = input ^ correction;
// Only test parity for 3-bit errors.
return popcount(syndrm) < 3 || !parity(output);
}
if ((it->a >> 8) == syndrm) {
// Build the correction from the compressed entry.
auto correction = ((((it->a & 0xFF) << 16) | it->b) << 1);
// Apply the correction to the input.
output = input ^ correction;
// Only test parity for 3-bit errors.
return popcount(syndrm) < 3 || !parity(output);
}
return false;
}
return false;
}
} // Golay24
} // Golay24
} // mobilinkd

Some files were not shown because too many files have changed in this diff Show More