mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-01-23 08:24:44 +01:00
Formatted the entire codebase and added a CI check for formatting
This commit is contained in:
parent
8644957881
commit
ea587db0cb
@ -17,7 +17,7 @@ AllowShortCaseLabelsOnASingleLine: false
|
|||||||
AllowShortFunctionsOnASingleLine: All
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortLambdasOnASingleLine: All
|
AllowShortLambdasOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: true
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
9
.github/workflows/build_all.yml
vendored
9
.github/workflows/build_all.yml
vendored
@ -359,3 +359,12 @@ jobs:
|
|||||||
|
|
||||||
- name: Running codespell
|
- name: Running codespell
|
||||||
run: cd $GITHUB_WORKSPACE && codespell -q 2 || true
|
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
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
ConfigManager::ConfigManager() {
|
ConfigManager::ConfigManager() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigManager::~ConfigManager() {
|
ConfigManager::~ConfigManager() {
|
||||||
@ -96,7 +95,7 @@ void ConfigManager::autoSaveWorker() {
|
|||||||
// Sleep but listen for wakeup call
|
// Sleep but listen for wakeup call
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(termMtx);
|
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; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,5 +33,4 @@ private:
|
|||||||
std::mutex termMtx;
|
std::mutex termMtx;
|
||||||
std::condition_variable termCond;
|
std::condition_variable termCond;
|
||||||
volatile bool termFlag = false;
|
volatile bool termFlag = false;
|
||||||
|
|
||||||
};
|
};
|
@ -30,11 +30,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INSTALL_PREFIX
|
#ifndef INSTALL_PREFIX
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define INSTALL_PREFIX "/usr/local"
|
#define INSTALL_PREFIX "/usr/local"
|
||||||
#else
|
#else
|
||||||
#define INSTALL_PREFIX "/usr"
|
#define INSTALL_PREFIX "/usr"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* OPENGL_VERSIONS_GLSL[] = {
|
const char* OPENGL_VERSIONS_GLSL[] = {
|
||||||
@ -99,7 +99,7 @@ static void maximized_callback(GLFWwindow* window, int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// main
|
// main
|
||||||
int sdrpp_main(int argc, char *argv[]) {
|
int sdrpp_main(int argc, char* argv[]) {
|
||||||
spdlog::info("SDR++ v" VERSION_STR);
|
spdlog::info("SDR++ v" VERSION_STR);
|
||||||
|
|
||||||
#ifdef IS_MACOS_BUNDLE
|
#ifdef IS_MACOS_BUNDLE
|
||||||
@ -321,8 +321,8 @@ int sdrpp_main(int argc, char *argv[]) {
|
|||||||
const char* glsl_version = "#version 150";
|
const char* glsl_version = "#version 150";
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
||||||
|
|
||||||
// Create window with graphics context
|
// Create window with graphics context
|
||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
@ -343,10 +343,10 @@ int sdrpp_main(int argc, char *argv[]) {
|
|||||||
monitor = glfwGetPrimaryMonitor();
|
monitor = glfwGetPrimaryMonitor();
|
||||||
core::window = glfwCreateWindow(winWidth, winHeight, "SDR++ v" VERSION_STR " (Built at " __TIME__ ", " __DATE__ ")", NULL, NULL);
|
core::window = glfwCreateWindow(winWidth, winHeight, "SDR++ v" VERSION_STR " (Built at " __TIME__ ", " __DATE__ ")", NULL, NULL);
|
||||||
if (core::window == 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;
|
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);
|
glfwMakeContextCurrent(core::window);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -370,15 +370,24 @@ int sdrpp_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
GLFWimage icons[10];
|
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[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[1].pixels = (unsigned char*)malloc(16 * 16 * 4);
|
||||||
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4); icons[2].width = icons[2].height = 24;
|
icons[1].width = icons[1].height = 16;
|
||||||
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4); icons[3].width = icons[3].height = 32;
|
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4);
|
||||||
icons[4].pixels = (unsigned char*)malloc(48 * 48 * 4); icons[4].width = icons[4].height = 48;
|
icons[2].width = icons[2].height = 24;
|
||||||
icons[5].pixels = (unsigned char*)malloc(64 * 64 * 4); icons[5].width = icons[5].height = 64;
|
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4);
|
||||||
icons[6].pixels = (unsigned char*)malloc(96 * 96 * 4); icons[6].width = icons[6].height = 96;
|
icons[3].width = icons[3].height = 32;
|
||||||
icons[7].pixels = (unsigned char*)malloc(128 * 128 * 4); icons[7].width = icons[7].height = 128;
|
icons[4].pixels = (unsigned char*)malloc(48 * 48 * 4);
|
||||||
icons[8].pixels = (unsigned char*)malloc(196 * 196 * 4); icons[8].width = icons[8].height = 196;
|
icons[4].width = icons[4].height = 48;
|
||||||
icons[9].pixels = (unsigned char*)malloc(256 * 256 * 4); icons[9].width = icons[9].height = 256;
|
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[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[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);
|
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
|
// Setup Dear ImGui context
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
(void)io;
|
||||||
io.IniFilename = NULL;
|
io.IniFilename = NULL;
|
||||||
|
|
||||||
// Setup Platform/Renderer bindings
|
// Setup Platform/Renderer bindings
|
||||||
@ -445,7 +455,7 @@ int sdrpp_main(int argc, char *argv[]) {
|
|||||||
fsWidth = _winWidth;
|
fsWidth = _winWidth;
|
||||||
fsHeight = _winHeight;
|
fsHeight = _winHeight;
|
||||||
glfwGetWindowPos(core::window, &fsPosX, &fsPosY);
|
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);
|
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) {
|
if (_maximized != maximized) {
|
||||||
_maximized = maximized;
|
_maximized = maximized;
|
||||||
core::configManager.acquire();
|
core::configManager.acquire();
|
||||||
core::configManager.conf["maximized"]= _maximized;
|
core::configManager.conf["maximized"] = _maximized;
|
||||||
if (!maximized) {
|
if (!maximized) {
|
||||||
glfwSetWindowSize(core::window, core::configManager.conf["windowSize"]["w"], core::configManager.conf["windowSize"]["h"]);
|
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;
|
fsWidth = _winWidth;
|
||||||
fsHeight = _winHeight;
|
fsHeight = _winHeight;
|
||||||
glfwGetWindowPos(core::window, &fsPosX, &fsPosY);
|
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);
|
glfwSetWindowMonitor(core::window, monitor, 0, 0, mode->width, mode->height, 0);
|
||||||
core::configManager.acquire();
|
core::configManager.acquire();
|
||||||
core::configManager.conf["fullscreen"] = true;
|
core::configManager.conf["fullscreen"] = true;
|
||||||
@ -491,7 +501,7 @@ int sdrpp_main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
spdlog::info("Fullscreen: OFF");
|
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.acquire();
|
||||||
core::configManager.conf["fullscreen"] = false;
|
core::configManager.conf["fullscreen"] = false;
|
||||||
core::configManager.release();
|
core::configManager.release();
|
||||||
|
@ -12,4 +12,4 @@ namespace core {
|
|||||||
void setInputSampleRate(double samplerate);
|
void setInputSampleRate(double samplerate);
|
||||||
};
|
};
|
||||||
|
|
||||||
int sdrpp_main(int argc, char *argv[]);
|
int sdrpp_main(int argc, char* argv[]);
|
@ -40,7 +40,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ChannelsToStereo : public generic_block<ChannelsToStereo> {
|
class ChannelsToStereo : public generic_block<ChannelsToStereo> {
|
||||||
@ -98,7 +97,6 @@ namespace dsp {
|
|||||||
stream<float>* _in_right;
|
stream<float>* _in_right;
|
||||||
|
|
||||||
float* nullbuf;
|
float* nullbuf;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StereoToMono : public generic_block<StereoToMono> {
|
class StereoToMono : public generic_block<StereoToMono> {
|
||||||
@ -151,9 +149,8 @@ namespace dsp {
|
|||||||
stream<float> out;
|
stream<float> out;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float* l_buf, *r_buf;
|
float *l_buf, *r_buf;
|
||||||
stream<stereo_t>* _in;
|
stream<stereo_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StereoToChannels : public generic_block<StereoToChannels> {
|
class StereoToChannels : public generic_block<StereoToChannels> {
|
||||||
@ -197,6 +194,5 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<stereo_t>* _in;
|
stream<stereo_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -76,7 +76,7 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void workerLoop() {
|
void workerLoop() {
|
||||||
while (run() >= 0);
|
while (run() >= 0) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void acquire() {
|
void acquire() {
|
||||||
@ -139,7 +139,6 @@ namespace dsp {
|
|||||||
bool running = false;
|
bool running = false;
|
||||||
bool tempStopped = false;
|
bool tempStopped = false;
|
||||||
std::thread workerThread;
|
std::thread workerThread;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class BLOCK>
|
template <class BLOCK>
|
||||||
@ -224,6 +223,5 @@ namespace dsp {
|
|||||||
protected:
|
protected:
|
||||||
bool _block_init = false;
|
bool _block_init = false;
|
||||||
std::mutex ctrlMtx;
|
std::mutex ctrlMtx;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -114,7 +114,7 @@ namespace dsp {
|
|||||||
int _r = getReadable();
|
int _r = getReadable();
|
||||||
if (_r != 0) { return _r; }
|
if (_r != 0) { return _r; }
|
||||||
std::unique_lock<std::mutex> lck(_readable_mtx);
|
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; }
|
if (_stopReader) { return -1; }
|
||||||
return getReadable(false);
|
return getReadable(false);
|
||||||
}
|
}
|
||||||
@ -164,7 +164,7 @@ namespace dsp {
|
|||||||
int _w = getWritable();
|
int _w = getWritable();
|
||||||
if (_w != 0) { return _w; }
|
if (_w != 0) { return _w; }
|
||||||
std::unique_lock<std::mutex> lck(_writable_mtx);
|
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; }
|
if (_stopWriter) { return -1; }
|
||||||
return getWritable(false);
|
return getWritable(false);
|
||||||
}
|
}
|
||||||
@ -173,7 +173,10 @@ namespace dsp {
|
|||||||
assert(_init);
|
assert(_init);
|
||||||
if (lock) { _writable_mtx.lock(); };
|
if (lock) { _writable_mtx.lock(); };
|
||||||
int _w = writable;
|
int _w = writable;
|
||||||
if (lock) { _writable_mtx.unlock(); _readable_mtx.lock(); };
|
if (lock) {
|
||||||
|
_writable_mtx.unlock();
|
||||||
|
_readable_mtx.lock();
|
||||||
|
};
|
||||||
int _r = readable;
|
int _r = readable;
|
||||||
if (lock) { _readable_mtx.unlock(); };
|
if (lock) { _readable_mtx.unlock(); };
|
||||||
return std::max<int>(std::min<int>(_w, maxLatency - _r), 0);
|
return std::max<int>(std::min<int>(_w, maxLatency - _r), 0);
|
||||||
@ -233,7 +236,7 @@ namespace dsp {
|
|||||||
std::condition_variable canWriteVar;
|
std::condition_variable canWriteVar;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TEST_BUFFER_SIZE 32
|
#define TEST_BUFFER_SIZE 32
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class SampleFrameBuffer : public generic_block<SampleFrameBuffer<T>> {
|
class SampleFrameBuffer : public generic_block<SampleFrameBuffer<T>> {
|
||||||
@ -303,7 +306,7 @@ namespace dsp {
|
|||||||
while (true) {
|
while (true) {
|
||||||
// Wait for data
|
// Wait for data
|
||||||
std::unique_lock lck(bufMtx);
|
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; }
|
if (stopWorker) { break; }
|
||||||
|
|
||||||
// Write one to output buffer and unlock in preparation to swap buffers
|
// Write one to output buffer and unlock in preparation to swap buffers
|
||||||
@ -354,6 +357,5 @@ namespace dsp {
|
|||||||
int sizes[TEST_BUFFER_SIZE];
|
int sizes[TEST_BUFFER_SIZE];
|
||||||
|
|
||||||
bool stopWorker = false;
|
bool stopWorker = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -203,6 +203,5 @@ namespace dsp {
|
|||||||
stream<T>* _input;
|
stream<T>* _input;
|
||||||
std::vector<ChainLinkAny<T>*> links;
|
std::vector<ChainLinkAny<T>*> links;
|
||||||
bool running = false;
|
bool running = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -65,10 +65,9 @@ namespace dsp {
|
|||||||
int counter = 0;
|
int counter = 0;
|
||||||
float lastVal = 0;
|
float lastVal = 0;
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template <class T>
|
||||||
class MMClockRecovery : public generic_block<MMClockRecovery<T>> {
|
class MMClockRecovery : public generic_block<MMClockRecovery<T>> {
|
||||||
public:
|
public:
|
||||||
MMClockRecovery() {}
|
MMClockRecovery() {}
|
||||||
@ -160,7 +159,7 @@ namespace dsp {
|
|||||||
out.writeBuf[outCount++] = outVal;
|
out.writeBuf[outCount++] = outVal;
|
||||||
|
|
||||||
// Cursed phase detect approximation (don't ask me how this approximation works)
|
// 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;
|
lastOutput = outVal;
|
||||||
}
|
}
|
||||||
if constexpr (std::is_same_v<T, complex_t> || std::is_same_v<T, stereo_t>) {
|
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
|
// TODO: Branchless clamp
|
||||||
_dynOmega = _dynOmega + (_gainOmega * phaseError);
|
_dynOmega = _dynOmega + (_gainOmega * phaseError);
|
||||||
if (_dynOmega > omegaMax) { _dynOmega = omegaMax; }
|
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
|
// Adjust the symbol phase according to the phase error approximation
|
||||||
// It will now contain the phase delta needed to jump to the next symbol
|
// It will now contain the phase delta needed to jump to the next symbol
|
||||||
@ -246,10 +247,9 @@ namespace dsp {
|
|||||||
float lastOutput = 0.0f;
|
float lastOutput = 0.0f;
|
||||||
|
|
||||||
// Cursed complex stuff
|
// Cursed complex stuff
|
||||||
complex_t _p_0T = {0,0}, _p_1T = {0,0}, _p_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};
|
complex_t _c_0T = { 0, 0 }, _c_1T = { 0, 0 }, _c_2T = { 0, 0 };
|
||||||
|
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -92,7 +92,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
PCMType _pcmType;
|
PCMType _pcmType;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DynamicRangeDecompressor : public generic_block<DynamicRangeDecompressor> {
|
class DynamicRangeDecompressor : public generic_block<DynamicRangeDecompressor> {
|
||||||
@ -156,6 +155,5 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -42,7 +42,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComplexToReal : public generic_block<ComplexToReal> {
|
class ComplexToReal : public generic_block<ComplexToReal> {
|
||||||
@ -83,7 +82,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComplexToImag : public generic_block<ComplexToImag> {
|
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);
|
volk_32fc_deinterleave_imag_32f(out.writeBuf, (lv_32fc_t*)_in->readBuf, count);
|
||||||
|
|
||||||
_in->flush();
|
_in->flush();
|
||||||
if(!out.swap(count)) { return -1; }
|
if (!out.swap(count)) { return -1; }
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +122,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -176,7 +173,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
float* nullBuffer;
|
float* nullBuffer;
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Int16CToComplex : public generic_block<Int16CToComplex> {
|
class Int16CToComplex : public generic_block<Int16CToComplex> {
|
||||||
@ -217,7 +213,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<int16_t>* _in;
|
stream<int16_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComplexToInt16C : public generic_block<ComplexToInt16C> {
|
class ComplexToInt16C : public generic_block<ComplexToInt16C> {
|
||||||
@ -258,7 +253,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Int16ToFloat : public generic_block<Int16ToFloat> {
|
class Int16ToFloat : public generic_block<Int16ToFloat> {
|
||||||
@ -299,7 +293,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<int16_t>* _in;
|
stream<int16_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatToInt16 : public generic_block<FloatToInt16> {
|
class FloatToInt16 : public generic_block<FloatToInt16> {
|
||||||
@ -340,6 +333,5 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -70,8 +70,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
float correctionRate = 0.00001;
|
float correctionRate = 0.00001;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DCBlocker : public generic_block<DCBlocker> {
|
class DCBlocker : public generic_block<DCBlocker> {
|
||||||
@ -138,8 +136,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
float correctionRate = 0.00001;
|
float correctionRate = 0.00001;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,14 +67,14 @@ namespace dsp {
|
|||||||
int outIndex = 0;
|
int outIndex = 0;
|
||||||
if constexpr (std::is_same_v<T, float>) {
|
if constexpr (std::is_same_v<T, float>) {
|
||||||
while (inIndex < count) {
|
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;
|
inIndex += 2;
|
||||||
outIndex++;
|
outIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constexpr (std::is_same_v<T, complex_t>) {
|
if constexpr (std::is_same_v<T, complex_t>) {
|
||||||
while (inIndex < count) {
|
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;
|
inIndex += 2;
|
||||||
outIndex++;
|
outIndex++;
|
||||||
}
|
}
|
||||||
@ -102,6 +102,5 @@ namespace dsp {
|
|||||||
int tapCount;
|
int tapCount;
|
||||||
float* taps;
|
float* taps;
|
||||||
int _inIndex = 0;
|
int _inIndex = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -2,8 +2,8 @@
|
|||||||
#include <dsp/block.h>
|
#include <dsp/block.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#define DSP_SIGN(n) ((n) >= 0)
|
#define DSP_SIGN(n) ((n) >= 0)
|
||||||
#define DSP_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)
|
#define DSP_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)
|
||||||
|
|
||||||
namespace dsp {
|
namespace dsp {
|
||||||
class Deframer : public generic_block<Deframer> {
|
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) {
|
void init(stream<uint8_t>* in, int frameLen, uint8_t* syncWord, int syncLen) {
|
||||||
_in = in;
|
_in = in;
|
||||||
_frameLen = frameLen;
|
_frameLen = frameLen;
|
||||||
_syncword = new uint8_t[syncLen];
|
_syncword = new uint8_t[syncLen];
|
||||||
_syncLen = syncLen;
|
_syncLen = syncLen;
|
||||||
memcpy(_syncword, syncWord, syncLen);
|
memcpy(_syncword, syncWord, syncLen);
|
||||||
|
|
||||||
@ -87,13 +87,13 @@ namespace dsp {
|
|||||||
bitsRead = 0;
|
bitsRead = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else { i++; }
|
else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
nextBitIsStartOfFrame = false;
|
nextBitIsStartOfFrame = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep last _syncLen4 symbols
|
// Keep last _syncLen4 symbols
|
||||||
@ -125,13 +125,12 @@ namespace dsp {
|
|||||||
int callcount = 0;
|
int callcount = 0;
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int MachesterHammingDistance(float* data, uint8_t* syncBits, int n) {
|
inline int MachesterHammingDistance(float* data, uint8_t* syncBits, int n) {
|
||||||
int dist = 0;
|
int dist = 0;
|
||||||
for (int i = 0; i < n; i++) {
|
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;
|
return dist;
|
||||||
}
|
}
|
||||||
@ -153,7 +152,7 @@ namespace dsp {
|
|||||||
void init(stream<float>* in, int frameLen, uint8_t* syncWord, int syncLen) {
|
void init(stream<float>* in, int frameLen, uint8_t* syncWord, int syncLen) {
|
||||||
_in = in;
|
_in = in;
|
||||||
_frameLen = frameLen;
|
_frameLen = frameLen;
|
||||||
_syncword = new uint8_t[syncLen];
|
_syncword = new uint8_t[syncLen];
|
||||||
_syncLen = syncLen;
|
_syncLen = syncLen;
|
||||||
memcpy(_syncword, syncWord, syncLen);
|
memcpy(_syncword, syncWord, syncLen);
|
||||||
|
|
||||||
@ -208,7 +207,6 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep last _syncLen symbols
|
// Keep last _syncLen symbols
|
||||||
@ -230,7 +228,6 @@ namespace dsp {
|
|||||||
int bitsRead = -1;
|
int bitsRead = -1;
|
||||||
|
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SymbolDeframer : public generic_block<SymbolDeframer> {
|
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) {
|
void init(stream<uint8_t>* in, int frameLen, uint8_t* syncWord, int syncLen) {
|
||||||
_in = in;
|
_in = in;
|
||||||
_frameLen = frameLen;
|
_frameLen = frameLen;
|
||||||
_syncword = new uint8_t[syncLen];
|
_syncword = new uint8_t[syncLen];
|
||||||
_syncLen = syncLen;
|
_syncLen = syncLen;
|
||||||
memcpy(_syncword, syncWord, syncLen);
|
memcpy(_syncword, syncWord, syncLen);
|
||||||
|
|
||||||
@ -297,7 +294,6 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep last _syncLen symbols
|
// Keep last _syncLen symbols
|
||||||
@ -319,7 +315,6 @@ namespace dsp {
|
|||||||
int bitsRead = -1;
|
int bitsRead = -1;
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ManchesterDecoder : public generic_block<ManchesterDecoder> {
|
class ManchesterDecoder : public generic_block<ManchesterDecoder> {
|
||||||
@ -352,12 +347,12 @@ namespace dsp {
|
|||||||
|
|
||||||
if (_inverted) {
|
if (_inverted) {
|
||||||
for (int i = 0; i < count; i += 2) {
|
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 {
|
else {
|
||||||
for (int i = 0; i < count; i += 2) {
|
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:
|
private:
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
bool _inverted;
|
bool _inverted;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BitPacker : public generic_block<BitPacker> {
|
class BitPacker : public generic_block<BitPacker> {
|
||||||
@ -415,8 +409,6 @@ namespace dsp {
|
|||||||
stream<uint8_t> out;
|
stream<uint8_t> out;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -13,14 +13,14 @@
|
|||||||
#include <dsp/stereo_fm.h>
|
#include <dsp/stereo_fm.h>
|
||||||
#include <dsp/correction.h>
|
#include <dsp/correction.h>
|
||||||
|
|
||||||
#define FAST_ATAN2_COEF1 FL_M_PI / 4.0f
|
#define FAST_ATAN2_COEF1 FL_M_PI / 4.0f
|
||||||
#define FAST_ATAN2_COEF2 3.0f * FAST_ATAN2_COEF1
|
#define FAST_ATAN2_COEF2 3.0f * FAST_ATAN2_COEF1
|
||||||
|
|
||||||
inline float fast_arctan2(float y, float x) {
|
inline float fast_arctan2(float y, float x) {
|
||||||
float abs_y = fabsf(y);
|
float abs_y = fabsf(y);
|
||||||
float r, angle;
|
float r, angle;
|
||||||
if (x == 0.0f && y == 0.0f) { return 0.0f; }
|
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);
|
r = (x - abs_y) / (x + abs_y);
|
||||||
angle = FAST_ATAN2_COEF1 - FAST_ATAN2_COEF1 * r;
|
angle = FAST_ATAN2_COEF1 - FAST_ATAN2_COEF1 * r;
|
||||||
}
|
}
|
||||||
@ -98,8 +98,10 @@ namespace dsp {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
currentPhase = fast_arctan2(_in->readBuf[i].im, _in->readBuf[i].re);
|
currentPhase = fast_arctan2(_in->readBuf[i].im, _in->readBuf[i].re);
|
||||||
diff = currentPhase - phase;
|
diff = currentPhase - phase;
|
||||||
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; }
|
else if (diff <= -3.1415926535f) {
|
||||||
|
diff += 2 * 3.1415926535f;
|
||||||
|
}
|
||||||
out.writeBuf[i] = diff / phasorSpeed;
|
out.writeBuf[i] = diff / phasorSpeed;
|
||||||
phase = currentPhase;
|
phase = currentPhase;
|
||||||
}
|
}
|
||||||
@ -115,7 +117,6 @@ namespace dsp {
|
|||||||
float phase = 0;
|
float phase = 0;
|
||||||
float phasorSpeed, _sampleRate, _deviation;
|
float phasorSpeed, _sampleRate, _deviation;
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FMDemod : public generic_block<FMDemod> {
|
class FMDemod : public generic_block<FMDemod> {
|
||||||
@ -179,8 +180,10 @@ namespace dsp {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
currentPhase = fast_arctan2(_in->readBuf[i].im, _in->readBuf[i].re);
|
currentPhase = fast_arctan2(_in->readBuf[i].im, _in->readBuf[i].re);
|
||||||
diff = currentPhase - phase;
|
diff = currentPhase - phase;
|
||||||
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; }
|
else if (diff <= -3.1415926535f) {
|
||||||
|
diff += 2 * 3.1415926535f;
|
||||||
|
}
|
||||||
out.writeBuf[i].l = diff / phasorSpeed;
|
out.writeBuf[i].l = diff / phasorSpeed;
|
||||||
out.writeBuf[i].r = diff / phasorSpeed;
|
out.writeBuf[i].r = diff / phasorSpeed;
|
||||||
phase = currentPhase;
|
phase = currentPhase;
|
||||||
@ -197,7 +200,6 @@ namespace dsp {
|
|||||||
float phase = 0;
|
float phase = 0;
|
||||||
float phasorSpeed, _sampleRate, _deviation;
|
float phasorSpeed, _sampleRate, _deviation;
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AMDemod : public generic_block<AMDemod> {
|
class AMDemod : public generic_block<AMDemod> {
|
||||||
@ -245,7 +247,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
float avg = 0;
|
float avg = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SSBDemod : public generic_block<SSBDemod> {
|
class SSBDemod : public generic_block<SSBDemod> {
|
||||||
@ -369,18 +370,17 @@ namespace dsp {
|
|||||||
lv_32fc_t* buffer;
|
lv_32fc_t* buffer;
|
||||||
lv_32fc_t phase;
|
lv_32fc_t phase;
|
||||||
lv_32fc_t phaseDelta;
|
lv_32fc_t phaseDelta;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FSKDemod : public generic_hier_block<FSKDemod> {
|
class FSKDemod : public generic_hier_block<FSKDemod> {
|
||||||
public:
|
public:
|
||||||
FSKDemod() {}
|
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);
|
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;
|
_sampleRate = sampleRate;
|
||||||
_deviation = deviation;
|
_deviation = deviation;
|
||||||
_baudRate = baudRate;
|
_baudRate = baudRate;
|
||||||
@ -455,11 +455,11 @@ namespace dsp {
|
|||||||
public:
|
public:
|
||||||
GFSKDemod() {}
|
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);
|
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;
|
_sampleRate = sampleRate;
|
||||||
_deviation = deviation;
|
_deviation = deviation;
|
||||||
_rrcAlpha = rrcAlpha;
|
_rrcAlpha = rrcAlpha;
|
||||||
@ -550,16 +550,16 @@ namespace dsp {
|
|||||||
float _omegaRelLimit;
|
float _omegaRelLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int ORDER, bool OFFSET>
|
template <int ORDER, bool OFFSET>
|
||||||
class PSKDemod : public generic_hier_block<PSKDemod<ORDER, OFFSET>> {
|
class PSKDemod : public generic_hier_block<PSKDemod<ORDER, OFFSET>> {
|
||||||
public:
|
public:
|
||||||
PSKDemod() {}
|
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);
|
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;
|
_RRCTapCount = RRCTapCount;
|
||||||
_RRCAlpha = RRCAlpha;
|
_RRCAlpha = RRCAlpha;
|
||||||
_sampleRate = sampleRate;
|
_sampleRate = sampleRate;
|
||||||
@ -683,11 +683,11 @@ namespace dsp {
|
|||||||
public:
|
public:
|
||||||
PMDemod() {}
|
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);
|
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;
|
_sampleRate = sampleRate;
|
||||||
_baudRate = baudRate;
|
_baudRate = baudRate;
|
||||||
_agcRate = agcRate;
|
_agcRate = agcRate;
|
||||||
|
@ -3,37 +3,36 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
// WTF???
|
// WTF???
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#include <correct.h>
|
#include <correct.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t toDB[] = {
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
0x3e, 0x45, 0xf2, 0x89, 0x5d, 0x26, 0x6b, 0x10, 0xc4, 0xbf
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t fromDB[] = {
|
const uint8_t fromDB[] = {
|
||||||
0x00, 0xcc, 0xac, 0x60, 0x79, 0xb5, 0xd5, 0x19, 0xf0, 0x3c, 0x5c, 0x90, 0x89, 0x45, 0x25, 0xe9, 0xfd, 0x31, 0x51, 0x9d,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
0xe1, 0x81, 0x4d, 0xa4, 0x68, 0x08, 0xc4, 0xdd, 0x11, 0x71, 0xbd
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t randVals[] = {
|
const uint8_t randVals[] = {
|
||||||
@ -92,29 +91,44 @@ namespace dsp {
|
|||||||
uint8_t* data = _in->readBuf + 4;
|
uint8_t* data = _in->readBuf + 4;
|
||||||
|
|
||||||
// Deinterleave
|
// Deinterleave
|
||||||
for (int i = 0; i < 255*5; i++) {
|
for (int i = 0; i < 255 * 5; i++) {
|
||||||
buffers[i%5][i/5] = fromDB[data[i]];
|
buffers[i % 5][i / 5] = fromDB[data[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reed the solomon :weary:
|
// Reed the solomon :weary:
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = correct_reed_solomon_decode(rs, buffers[0], 255, outBuffers[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]);
|
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]);
|
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]);
|
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]);
|
result = correct_reed_solomon_decode(rs, buffers[4], 255, outBuffers[4]);
|
||||||
if (result == -1) { _in->flush(); return count; }
|
if (result == -1) {
|
||||||
|
_in->flush();
|
||||||
// Reinterleave
|
return count;
|
||||||
for (int i = 0; i < 255*5; i++) {
|
|
||||||
out.writeBuf[i] = toDB[outBuffers[i%5][i/5]] ^ randVals[i % 255];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
_in->flush();
|
||||||
return count;
|
return count;
|
||||||
@ -129,6 +143,5 @@ namespace dsp {
|
|||||||
correct_reed_solomon* rs;
|
correct_reed_solomon* rs;
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -92,8 +92,7 @@ namespace dsp {
|
|||||||
break;
|
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 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)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 the packet doesn't fit the frame, save and go to next frame
|
||||||
if (dataLen - i < length) {
|
if (dataLen - i < length) {
|
||||||
@ -106,7 +105,6 @@ namespace dsp {
|
|||||||
memcpy(out.writeBuf, &data[i], length);
|
memcpy(out.writeBuf, &data[i], length);
|
||||||
out.swap(length);
|
out.swap(length);
|
||||||
i += length;
|
i += length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_in->flush();
|
_in->flush();
|
||||||
@ -123,6 +121,5 @@ namespace dsp {
|
|||||||
uint8_t packet[0x4008];
|
uint8_t packet[0x4008];
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -66,12 +66,12 @@ namespace dsp {
|
|||||||
|
|
||||||
if constexpr (std::is_same_v<T, float>) {
|
if constexpr (std::is_same_v<T, float>) {
|
||||||
for (int i = 0; i < count; i++) {
|
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>) {
|
if constexpr (std::is_same_v<T, complex_t>) {
|
||||||
for (int i = 0; i < count; i++) {
|
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;
|
T* buffer;
|
||||||
int tapCount;
|
int tapCount;
|
||||||
float* taps;
|
float* taps;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComplexFIR : public generic_block<ComplexFIR> {
|
class ComplexFIR : public generic_block<ComplexFIR> {
|
||||||
@ -157,7 +156,7 @@ namespace dsp {
|
|||||||
_in->flush();
|
_in->flush();
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
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; }
|
if (!out.swap(count)) { return -1; }
|
||||||
@ -180,7 +179,6 @@ namespace dsp {
|
|||||||
complex_t* buffer;
|
complex_t* buffer;
|
||||||
int tapCount;
|
int tapCount;
|
||||||
complex_t* taps;
|
complex_t* taps;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BFMDeemp : public generic_block<BFMDeemp> {
|
class BFMDeemp : public generic_block<BFMDeemp> {
|
||||||
@ -241,8 +239,8 @@ namespace dsp {
|
|||||||
if (isnan(lastOutR)) {
|
if (isnan(lastOutR)) {
|
||||||
lastOutR = 0.0f;
|
lastOutR = 0.0f;
|
||||||
}
|
}
|
||||||
out.writeBuf[0].l = (alpha * _in->readBuf[0].l) + ((1-alpha) * lastOutL);
|
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].r = (alpha * _in->readBuf[0].r) + ((1 - alpha) * lastOutR);
|
||||||
for (int i = 1; i < count; i++) {
|
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].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);
|
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 _tau;
|
||||||
float _sampleRate;
|
float _sampleRate;
|
||||||
stream<stereo_t>* _in;
|
stream<stereo_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -82,7 +82,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<T>* _a;
|
stream<T>* _a;
|
||||||
stream<T>* _b;
|
stream<T>* _b;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -163,7 +162,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<T>* _a;
|
stream<T>* _a;
|
||||||
stream<T>* _b;
|
stream<T>* _b;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -244,6 +242,5 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<T>* _a;
|
stream<T>* _a;
|
||||||
stream<T>* _b;
|
stream<T>* _b;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -77,6 +77,5 @@ namespace dsp {
|
|||||||
float lvlR = -90.0f;
|
float lvlR = -90.0f;
|
||||||
stream<stereo_t>* _in;
|
stream<stereo_t>* _in;
|
||||||
std::mutex lvlMtx;
|
std::mutex lvlMtx;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -61,7 +61,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -72,7 +72,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,12 +9,12 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t HRPTSyncWord[] = {
|
const uint8_t HRPTSyncWord[] = {
|
||||||
1,0,1,0,0,0,0,1,0,0,
|
1, 0, 1, 0, 0, 0, 0, 1, 0, 0,
|
||||||
0,1,0,1,1,0,1,1,1,1,
|
0, 1, 0, 1, 1, 0, 1, 1, 1, 1,
|
||||||
1,1,0,1,0,1,1,1,0,0,
|
1, 1, 0, 1, 0, 1, 1, 1, 0, 0,
|
||||||
0,1,1,0,0,1,1,1,0,1,
|
0, 1, 1, 0, 0, 1, 1, 1, 0, 1,
|
||||||
1,0,0,0,0,0,1,1,1,1,
|
1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||||
0,0,1,0,0,1,0,1,0,1
|
0, 0, 1, 0, 0, 1, 0, 1, 0, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
class HRPTDemux : public generic_block<HRPTDemux> {
|
class HRPTDemux : public generic_block<HRPTDemux> {
|
||||||
@ -105,7 +105,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline uint16_t HIRSSignedToUnsigned(uint16_t n) {
|
inline uint16_t HIRSSignedToUnsigned(uint16_t n) {
|
||||||
@ -236,7 +235,6 @@ namespace dsp {
|
|||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
int lastElement = 0;
|
int lastElement = 0;
|
||||||
bool newImageData = false;
|
bool newImageData = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <dsp/utils/window_functions.h>
|
#include <dsp/utils/window_functions.h>
|
||||||
#include <fftw3.h>
|
#include <fftw3.h>
|
||||||
|
|
||||||
#define NR_TAP_COUNT 64
|
#define NR_TAP_COUNT 64
|
||||||
|
|
||||||
namespace dsp {
|
namespace dsp {
|
||||||
class FMIFNoiseReduction : public generic_block<FMIFNoiseReduction> {
|
class FMIFNoiseReduction : public generic_block<FMIFNoiseReduction> {
|
||||||
@ -30,21 +30,21 @@ namespace dsp {
|
|||||||
_in = in;
|
_in = in;
|
||||||
_tapCount = tapCount;
|
_tapCount = tapCount;
|
||||||
|
|
||||||
delay = (complex_t*)fftwf_malloc(sizeof(complex_t)*STREAM_BUFFER_SIZE);
|
delay = (complex_t*)fftwf_malloc(sizeof(complex_t) * STREAM_BUFFER_SIZE);
|
||||||
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
|
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
|
||||||
fft_window = (float*)fftwf_malloc(sizeof(float)*_tapCount);
|
fft_window = (float*)fftwf_malloc(sizeof(float) * _tapCount);
|
||||||
amp_buf = (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_cout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
|
||||||
fft_cin = (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);
|
fft_fcout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
|
||||||
delay_start = &delay[_tapCount];
|
delay_start = &delay[_tapCount];
|
||||||
|
|
||||||
memset(delay, 0, sizeof(complex_t)*STREAM_BUFFER_SIZE);
|
memset(delay, 0, sizeof(complex_t) * STREAM_BUFFER_SIZE);
|
||||||
memset(fft_in, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_in, 0, sizeof(complex_t) * _tapCount);
|
||||||
memset(amp_buf, 0, sizeof(float)*_tapCount);
|
memset(amp_buf, 0, sizeof(float) * _tapCount);
|
||||||
memset(fft_cout, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_cout, 0, sizeof(complex_t) * _tapCount);
|
||||||
memset(fft_cin, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_cin, 0, sizeof(complex_t) * _tapCount);
|
||||||
memset(fft_fcout, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_fcout, 0, sizeof(complex_t) * _tapCount);
|
||||||
|
|
||||||
for (int i = 0; i < _tapCount; i++) {
|
for (int i = 0; i < _tapCount; i++) {
|
||||||
fft_window[i] = window_function::blackman(i, _tapCount - 1);
|
fft_window[i] = window_function::blackman(i, _tapCount - 1);
|
||||||
@ -86,21 +86,21 @@ namespace dsp {
|
|||||||
fftwf_free(fft_cin);
|
fftwf_free(fft_cin);
|
||||||
fftwf_free(fft_fcout);
|
fftwf_free(fft_fcout);
|
||||||
|
|
||||||
delay = (complex_t*)fftwf_malloc(sizeof(complex_t)*STREAM_BUFFER_SIZE);
|
delay = (complex_t*)fftwf_malloc(sizeof(complex_t) * STREAM_BUFFER_SIZE);
|
||||||
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t)*_tapCount);
|
fft_in = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
|
||||||
fft_window = (float*)fftwf_malloc(sizeof(float)*_tapCount);
|
fft_window = (float*)fftwf_malloc(sizeof(float) * _tapCount);
|
||||||
amp_buf = (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_cout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
|
||||||
fft_cin = (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);
|
fft_fcout = (complex_t*)fftwf_malloc(sizeof(complex_t) * _tapCount);
|
||||||
delay_start = &delay[_tapCount];
|
delay_start = &delay[_tapCount];
|
||||||
|
|
||||||
memset(delay, 0, sizeof(complex_t)*STREAM_BUFFER_SIZE);
|
memset(delay, 0, sizeof(complex_t) * STREAM_BUFFER_SIZE);
|
||||||
memset(fft_in, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_in, 0, sizeof(complex_t) * _tapCount);
|
||||||
memset(amp_buf, 0, sizeof(float)*_tapCount);
|
memset(amp_buf, 0, sizeof(float) * _tapCount);
|
||||||
memset(fft_cout, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_cout, 0, sizeof(complex_t) * _tapCount);
|
||||||
memset(fft_cin, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_cin, 0, sizeof(complex_t) * _tapCount);
|
||||||
memset(fft_fcout, 0, sizeof(complex_t)*_tapCount);
|
memset(fft_fcout, 0, sizeof(complex_t) * _tapCount);
|
||||||
|
|
||||||
for (int i = 0; i < _tapCount; i++) {
|
for (int i = 0; i < _tapCount; i++) {
|
||||||
fft_window[i] = window_function::blackman(i, _tapCount - 1);
|
fft_window[i] = window_function::blackman(i, _tapCount - 1);
|
||||||
@ -154,13 +154,13 @@ namespace dsp {
|
|||||||
|
|
||||||
// Do reverse FFT and get first element
|
// Do reverse FFT and get first element
|
||||||
fftwf_execute(backwardPlan);
|
fftwf_execute(backwardPlan);
|
||||||
out.writeBuf[i] = fft_fcout[_tapCount/2];
|
out.writeBuf[i] = fft_fcout[_tapCount / 2];
|
||||||
|
|
||||||
// Reset the input buffer
|
// 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
|
// Copy last values to delay
|
||||||
memmove(delay, &delay[count], _tapCount * sizeof(complex_t));
|
memmove(delay, &delay[count], _tapCount * sizeof(complex_t));
|
||||||
@ -189,7 +189,6 @@ namespace dsp {
|
|||||||
complex_t* fft_fcout;
|
complex_t* fft_fcout;
|
||||||
|
|
||||||
int _tapCount;
|
int _tapCount;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FFTNoiseReduction : public generic_block<FFTNoiseReduction> {
|
class FFTNoiseReduction : public generic_block<FFTNoiseReduction> {
|
||||||
@ -214,19 +213,19 @@ namespace dsp {
|
|||||||
void init(stream<float>* in) {
|
void init(stream<float>* in) {
|
||||||
_in = in;
|
_in = in;
|
||||||
|
|
||||||
delay = (float*)fftwf_malloc(sizeof(float)*STREAM_BUFFER_SIZE);
|
delay = (float*)fftwf_malloc(sizeof(float) * STREAM_BUFFER_SIZE);
|
||||||
fft_in = (float*)fftwf_malloc(sizeof(float)*NR_TAP_COUNT);
|
fft_in = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
|
||||||
fft_window = (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);
|
amp_buf = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
|
||||||
fft_cout = (complex_t*)fftwf_malloc(sizeof(complex_t)*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);
|
fft_fout = (float*)fftwf_malloc(sizeof(float) * NR_TAP_COUNT);
|
||||||
delay_start = &delay[NR_TAP_COUNT];
|
delay_start = &delay[NR_TAP_COUNT];
|
||||||
|
|
||||||
memset(delay, 0, sizeof(float)*STREAM_BUFFER_SIZE);
|
memset(delay, 0, sizeof(float) * STREAM_BUFFER_SIZE);
|
||||||
memset(fft_in, 0, sizeof(float)*NR_TAP_COUNT);
|
memset(fft_in, 0, sizeof(float) * NR_TAP_COUNT);
|
||||||
memset(amp_buf, 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_cout, 0, sizeof(complex_t) * NR_TAP_COUNT);
|
||||||
memset(fft_fout, 0, sizeof(float)*NR_TAP_COUNT);
|
memset(fft_fout, 0, sizeof(float) * NR_TAP_COUNT);
|
||||||
|
|
||||||
for (int i = 0; i < NR_TAP_COUNT; i++) {
|
for (int i = 0; i < NR_TAP_COUNT; i++) {
|
||||||
fft_window[i] = window_function::blackman(i, NR_TAP_COUNT - 1);
|
fft_window[i] = window_function::blackman(i, NR_TAP_COUNT - 1);
|
||||||
@ -274,19 +273,19 @@ namespace dsp {
|
|||||||
fftwf_execute(forwardPlan);
|
fftwf_execute(forwardPlan);
|
||||||
|
|
||||||
// Process bins here
|
// Process bins here
|
||||||
volk_32fc_magnitude_32f(amp_buf, (lv_32fc_t*)fft_cout, NR_TAP_COUNT/2);
|
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++) {
|
for (int j = 1; j < NR_TAP_COUNT / 2; j++) {
|
||||||
if (log10f(amp_buf[0]) < level) {
|
if (log10f(amp_buf[0]) < level) {
|
||||||
fft_cout[j] = {0, 0};
|
fft_cout[j] = { 0, 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do reverse FFT and get first element
|
// Do reverse FFT and get first element
|
||||||
fftwf_execute(backwardPlan);
|
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
|
// Copy last values to delay
|
||||||
memmove(delay, &delay[count], NR_TAP_COUNT * sizeof(float));
|
memmove(delay, &delay[count], NR_TAP_COUNT * sizeof(float));
|
||||||
@ -312,7 +311,6 @@ namespace dsp {
|
|||||||
float* delay_start;
|
float* delay_start;
|
||||||
complex_t* fft_cout;
|
complex_t* fft_cout;
|
||||||
float* fft_fout;
|
float* fft_fout;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NoiseBlanker : public generic_block<NoiseBlanker> {
|
class NoiseBlanker : public generic_block<NoiseBlanker> {
|
||||||
@ -329,9 +327,10 @@ namespace dsp {
|
|||||||
|
|
||||||
void init(stream<complex_t>* in, float level) {
|
void init(stream<complex_t>* in, float level) {
|
||||||
_in = in;
|
_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>::registerInput(_in);
|
||||||
generic_block<NoiseBlanker>::registerOutput(&out);
|
generic_block<NoiseBlanker>::registerOutput(&out);
|
||||||
@ -379,7 +378,6 @@ namespace dsp {
|
|||||||
float _level;
|
float _level;
|
||||||
|
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class NotchFilter : public generic_block<NotchFilter> {
|
class NotchFilter : public generic_block<NotchFilter> {
|
||||||
@ -395,7 +393,7 @@ namespace dsp {
|
|||||||
_sampleRate = sampleRate;
|
_sampleRate = sampleRate;
|
||||||
|
|
||||||
phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
|
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>::registerInput(_in);
|
||||||
generic_block<NotchFilter>::registerOutput(&out);
|
generic_block<NotchFilter>::registerOutput(&out);
|
||||||
@ -419,13 +417,13 @@ namespace dsp {
|
|||||||
void setOffset(float offset) {
|
void setOffset(float offset) {
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
|
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) {
|
void setSampleRate(float sampleRate) {
|
||||||
_sampleRate = sampleRate;
|
_sampleRate = sampleRate;
|
||||||
phaseDelta = lv_cmake(std::cos((-_offset / _sampleRate) * 2.0f * FL_M_PI), std::sin((-_offset / _sampleRate) * 2.0f * FL_M_PI));
|
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() {
|
int run() {
|
||||||
@ -452,14 +450,13 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
complex_t offset = {0, 0};
|
complex_t offset = { 0, 0 };
|
||||||
lv_32fc_t inPhase = {1, 0};
|
lv_32fc_t inPhase = { 1, 0 };
|
||||||
lv_32fc_t outPhase = {4, 0};
|
lv_32fc_t outPhase = { 4, 0 };
|
||||||
lv_32fc_t phaseDelta;
|
lv_32fc_t phaseDelta;
|
||||||
lv_32fc_t phaseDeltaConj;
|
lv_32fc_t phaseDeltaConj;
|
||||||
float _offset;
|
float _offset;
|
||||||
float _sampleRate;
|
float _sampleRate;
|
||||||
float correctionRate;
|
float correctionRate;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace dsp {
|
namespace dsp {
|
||||||
template <int ORDER>
|
template <int ORDER>
|
||||||
class CostasLoop: public generic_block<CostasLoop<ORDER>> {
|
class CostasLoop : public generic_block<CostasLoop<ORDER>> {
|
||||||
public:
|
public:
|
||||||
CostasLoop() {}
|
CostasLoop() {}
|
||||||
|
|
||||||
@ -59,8 +59,8 @@ namespace dsp {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
// Mix the VFO with the input to create the output value
|
// 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.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.im = (lastVCO.im * _in->readBuf[i].re) + (lastVCO.re * _in->readBuf[i].im);
|
||||||
out.writeBuf[i] = outVal;
|
out.writeBuf[i] = outVal;
|
||||||
|
|
||||||
// Calculate the phase error estimation
|
// Calculate the phase error estimation
|
||||||
@ -75,20 +75,25 @@ namespace dsp {
|
|||||||
const float K = (sqrtf(2.0) - 1);
|
const float K = (sqrtf(2.0) - 1);
|
||||||
if (fabsf(outVal.re) >= fabsf(outVal.im)) {
|
if (fabsf(outVal.re) >= fabsf(outVal.im)) {
|
||||||
error = ((outVal.re > 0.0f ? 1.0f : -1.0f) * outVal.im -
|
error = ((outVal.re > 0.0f ? 1.0f : -1.0f) * outVal.im -
|
||||||
(outVal.im > 0.0f ? 1.0f : -1.0f) * outVal.re * K);
|
(outVal.im > 0.0f ? 1.0f : -1.0f) * outVal.re * K);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
error = ((outVal.re > 0.0f ? 1.0f : -1.0f) * outVal.im * K -
|
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; }
|
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
|
// Integrate frequency and clamp it
|
||||||
vcoFrequency += _beta * error;
|
vcoFrequency += _beta * error;
|
||||||
if (vcoFrequency > 1.0f) { vcoFrequency = 1.0f; }
|
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
|
// Calculate new phase and wrap it
|
||||||
vcoPhase += vcoFrequency + (_alpha * error);
|
vcoPhase += vcoFrequency + (_alpha * error);
|
||||||
@ -98,7 +103,6 @@ namespace dsp {
|
|||||||
// Calculate output
|
// Calculate output
|
||||||
lastVCO.re = cosf(-vcoPhase);
|
lastVCO.re = cosf(-vcoPhase);
|
||||||
lastVCO.im = sinf(-vcoPhase);
|
lastVCO.im = sinf(-vcoPhase);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_in->flush();
|
_in->flush();
|
||||||
@ -112,17 +116,16 @@ namespace dsp {
|
|||||||
float _loopBandwidth = 1.0f;
|
float _loopBandwidth = 1.0f;
|
||||||
|
|
||||||
float _alpha; // Integral coefficient
|
float _alpha; // Integral coefficient
|
||||||
float _beta; // Proportional coefficient
|
float _beta; // Proportional coefficient
|
||||||
float vcoFrequency = 0.0f;
|
float vcoFrequency = 0.0f;
|
||||||
float vcoPhase = 0.0f;
|
float vcoPhase = 0.0f;
|
||||||
complex_t lastVCO;
|
complex_t lastVCO;
|
||||||
|
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class CarrierTrackingPLL: public generic_block<CarrierTrackingPLL<T>> {
|
class CarrierTrackingPLL : public generic_block<CarrierTrackingPLL<T>> {
|
||||||
public:
|
public:
|
||||||
CarrierTrackingPLL() {}
|
CarrierTrackingPLL() {}
|
||||||
|
|
||||||
@ -174,8 +177,8 @@ namespace dsp {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
// Mix the VFO with the input to create the output value
|
// 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.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.im = ((-lastVCO.im) * _in->readBuf[i].re) + (lastVCO.re * _in->readBuf[i].im);
|
||||||
|
|
||||||
if constexpr (std::is_same_v<T, float>) {
|
if constexpr (std::is_same_v<T, float>) {
|
||||||
out.writeBuf[i] = outVal.fastPhase();
|
out.writeBuf[i] = outVal.fastPhase();
|
||||||
@ -187,8 +190,10 @@ namespace dsp {
|
|||||||
// Calculate the phase error estimation
|
// Calculate the phase error estimation
|
||||||
// TODO: Figure out why fastPhase doesn't work
|
// TODO: Figure out why fastPhase doesn't work
|
||||||
error = _in->readBuf[i].phase() - vcoPhase;
|
error = _in->readBuf[i].phase() - vcoPhase;
|
||||||
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; }
|
else if (error <= -3.1415926535f) {
|
||||||
|
error += 2.0f * 3.1415926535f;
|
||||||
|
}
|
||||||
|
|
||||||
// if (error > 1.0f) { error = 1.0f; }
|
// if (error > 1.0f) { error = 1.0f; }
|
||||||
// else 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
|
// Integrate frequency and clamp it
|
||||||
vcoFrequency += _beta * error;
|
vcoFrequency += _beta * error;
|
||||||
if (vcoFrequency > 1.0f) { vcoFrequency = 1.0f; }
|
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
|
// Calculate new phase and wrap it
|
||||||
vcoPhase += vcoFrequency + (_alpha * error);
|
vcoPhase += vcoFrequency + (_alpha * error);
|
||||||
@ -206,7 +213,6 @@ namespace dsp {
|
|||||||
// Calculate output
|
// Calculate output
|
||||||
lastVCO.re = cosf(vcoPhase);
|
lastVCO.re = cosf(vcoPhase);
|
||||||
lastVCO.im = sinf(vcoPhase);
|
lastVCO.im = sinf(vcoPhase);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_in->flush();
|
_in->flush();
|
||||||
@ -220,16 +226,15 @@ namespace dsp {
|
|||||||
float _loopBandwidth = 1.0f;
|
float _loopBandwidth = 1.0f;
|
||||||
|
|
||||||
float _alpha; // Integral coefficient
|
float _alpha; // Integral coefficient
|
||||||
float _beta; // Proportional coefficient
|
float _beta; // Proportional coefficient
|
||||||
float vcoFrequency = 0.0f;
|
float vcoFrequency = 0.0f;
|
||||||
float vcoPhase = 0.0f;
|
float vcoPhase = 0.0f;
|
||||||
complex_t lastVCO;
|
complex_t lastVCO;
|
||||||
|
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PLL: public generic_block<PLL> {
|
class PLL : public generic_block<PLL> {
|
||||||
public:
|
public:
|
||||||
PLL() {}
|
PLL() {}
|
||||||
|
|
||||||
@ -284,13 +289,17 @@ namespace dsp {
|
|||||||
// Calculate the phase error estimation
|
// Calculate the phase error estimation
|
||||||
// TODO: Figure out why fastPhase doesn't work
|
// TODO: Figure out why fastPhase doesn't work
|
||||||
error = _in->readBuf[i].phase() - vcoPhase;
|
error = _in->readBuf[i].phase() - vcoPhase;
|
||||||
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; }
|
else if (error <= -3.1415926535f) {
|
||||||
|
error += 2.0f * 3.1415926535f;
|
||||||
|
}
|
||||||
|
|
||||||
// Integrate frequency and clamp it
|
// Integrate frequency and clamp it
|
||||||
vcoFrequency += _beta * error;
|
vcoFrequency += _beta * error;
|
||||||
if (vcoFrequency > 1.0f) { vcoFrequency = 1.0f; }
|
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
|
// Calculate new phase and wrap it
|
||||||
vcoPhase += vcoFrequency + (_alpha * error);
|
vcoPhase += vcoFrequency + (_alpha * error);
|
||||||
@ -300,7 +309,6 @@ namespace dsp {
|
|||||||
// Calculate output
|
// Calculate output
|
||||||
lastVCO.re = cosf(vcoPhase);
|
lastVCO.re = cosf(vcoPhase);
|
||||||
lastVCO.im = sinf(vcoPhase);
|
lastVCO.im = sinf(vcoPhase);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_in->flush();
|
_in->flush();
|
||||||
@ -314,12 +322,11 @@ namespace dsp {
|
|||||||
float _loopBandwidth = 1.0f;
|
float _loopBandwidth = 1.0f;
|
||||||
|
|
||||||
float _alpha; // Integral coefficient
|
float _alpha; // Integral coefficient
|
||||||
float _beta; // Proportional coefficient
|
float _beta; // Proportional coefficient
|
||||||
float vcoFrequency = ((19000.0f / 250000.0f) * 2.0f * FL_M_PI);
|
float vcoFrequency = ((19000.0f / 250000.0f) * 2.0f * FL_M_PI);
|
||||||
float vcoPhase = 0.0f;
|
float vcoPhase = 0.0f;
|
||||||
complex_t lastVCO;
|
complex_t lastVCO;
|
||||||
|
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -82,7 +82,6 @@ namespace dsp {
|
|||||||
lv_32fc_t phaseDelta;
|
lv_32fc_t phaseDelta;
|
||||||
lv_32fc_t phase;
|
lv_32fc_t phase;
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AGC : public generic_block<AGC> {
|
class AGC : public generic_block<AGC> {
|
||||||
@ -155,7 +154,6 @@ namespace dsp {
|
|||||||
float _CorrectedFallRate;
|
float _CorrectedFallRate;
|
||||||
float _sampleRate;
|
float _sampleRate;
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ComplexAGC : public generic_block<ComplexAGC> {
|
class ComplexAGC : public generic_block<ComplexAGC> {
|
||||||
@ -225,7 +223,6 @@ namespace dsp {
|
|||||||
float _rate = 10e-4;
|
float _rate = 10e-4;
|
||||||
|
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DelayImag : public generic_block<DelayImag> {
|
class DelayImag : public generic_block<DelayImag> {
|
||||||
@ -273,11 +270,9 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
float lastIm = 0.0f;
|
float lastIm = 0.0f;
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Volume : public generic_block<Volume<T>> {
|
class Volume : public generic_block<Volume<T>> {
|
||||||
public:
|
public:
|
||||||
@ -358,7 +353,6 @@ namespace dsp {
|
|||||||
float _volume = 1.0f;
|
float _volume = 1.0f;
|
||||||
bool _muted = false;
|
bool _muted = false;
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Squelch : public generic_block<Squelch> {
|
class Squelch : public generic_block<Squelch> {
|
||||||
@ -431,7 +425,6 @@ namespace dsp {
|
|||||||
float* normBuffer;
|
float* normBuffer;
|
||||||
float _level = -50.0f;
|
float _level = -50.0f;
|
||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -497,7 +490,6 @@ namespace dsp {
|
|||||||
int samples = 1;
|
int samples = 1;
|
||||||
int read = 0;
|
int read = 0;
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Threshold : public generic_block<Threshold> {
|
class Threshold : public generic_block<Threshold> {
|
||||||
@ -561,7 +553,6 @@ namespace dsp {
|
|||||||
float* normBuffer;
|
float* normBuffer;
|
||||||
float _level = -50.0f;
|
float _level = -50.0f;
|
||||||
stream<float>* _in;
|
stream<float>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BFMPilotToStereo : public generic_block<BFMPilotToStereo> {
|
class BFMPilotToStereo : public generic_block<BFMPilotToStereo> {
|
||||||
@ -614,6 +605,5 @@ namespace dsp {
|
|||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
|
|
||||||
complex_t* buffer;
|
complex_t* buffer;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -160,39 +160,39 @@ namespace dsp {
|
|||||||
stream<T> out;
|
stream<T> out;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void buildTapPhases(){
|
void buildTapPhases() {
|
||||||
if(!taps){
|
if (!taps) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!tapPhases.empty()){
|
if (!tapPhases.empty()) {
|
||||||
freeTapPhases();
|
freeTapPhases();
|
||||||
}
|
}
|
||||||
|
|
||||||
int phases = _interp;
|
int phases = _interp;
|
||||||
tapsPerPhase = (tapCount+phases-1)/phases; //Integer division ceiling
|
tapsPerPhase = (tapCount + phases - 1) / phases; //Integer division ceiling
|
||||||
|
|
||||||
bufStart = &buffer[tapsPerPhase];
|
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()));
|
tapPhases.push_back((float*)volk_malloc(tapsPerPhase * sizeof(float), volk_get_alignment()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int currentTap = 0;
|
int currentTap = 0;
|
||||||
for(int tap = 0; tap < tapsPerPhase; tap++) {
|
for (int tap = 0; tap < tapsPerPhase; tap++) {
|
||||||
for (int phase = 0; phase < phases; phase++) {
|
for (int phase = 0; phase < phases; phase++) {
|
||||||
if(currentTap < tapCount) {
|
if (currentTap < tapCount) {
|
||||||
tapPhases[(_interp - 1) - phase][tap] = taps[currentTap++];
|
tapPhases[(_interp - 1) - phase][tap] = taps[currentTap++];
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
tapPhases[(_interp - 1) - phase][tap] = 0;
|
tapPhases[(_interp - 1) - phase][tap] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeTapPhases(){
|
void freeTapPhases() {
|
||||||
for(auto & tapPhase : tapPhases){
|
for (auto& tapPhase : tapPhases) {
|
||||||
volk_free(tapPhase);
|
volk_free(tapPhase);
|
||||||
}
|
}
|
||||||
tapPhases.clear();
|
tapPhases.clear();
|
||||||
@ -214,6 +214,5 @@ namespace dsp {
|
|||||||
|
|
||||||
int tapsPerPhase;
|
int tapsPerPhase;
|
||||||
std::vector<float*> tapPhases;
|
std::vector<float*> tapPhases;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -62,7 +62,6 @@ namespace dsp {
|
|||||||
|
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
std::vector<stream<T>*> out;
|
std::vector<stream<T>*> out;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -110,7 +109,6 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -183,7 +181,8 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
while (run() >= 0);
|
while (run() >= 0)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doStop() override {
|
void doStop() override {
|
||||||
@ -240,6 +239,5 @@ namespace dsp {
|
|||||||
std::thread bufferWorkerThread;
|
std::thread bufferWorkerThread;
|
||||||
std::thread workThread;
|
std::thread workThread;
|
||||||
int _keep, _skip;
|
int _keep, _skip;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -50,7 +50,6 @@ namespace dsp {
|
|||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
void (*_handler)(T* data, int count, void* ctx);
|
void (*_handler)(T* data, int count, void* ctx);
|
||||||
void* _ctx;
|
void* _ctx;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -99,7 +98,6 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -134,7 +132,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -188,6 +185,5 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
stream<T>* _in;
|
stream<T>* _in;
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -60,7 +60,7 @@ namespace dsp {
|
|||||||
|
|
||||||
int run() {
|
int run() {
|
||||||
volk_32fc_s32fc_x2_rotator_32fc((lv_32fc_t*)out.writeBuf, zeroPhase, phaseDelta, &phase, _blockSize);
|
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;
|
return _blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,6 @@ namespace dsp {
|
|||||||
lv_32fc_t phaseDelta;
|
lv_32fc_t phaseDelta;
|
||||||
lv_32fc_t phase;
|
lv_32fc_t phase;
|
||||||
lv_32fc_t* zeroPhase;
|
lv_32fc_t* zeroPhase;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -111,6 +110,5 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
int (*_handler)(T* data, void* ctx);
|
int (*_handler)(T* data, void* ctx);
|
||||||
void* _ctx;
|
void* _ctx;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -66,10 +66,10 @@ namespace dsp {
|
|||||||
_in->flush();
|
_in->flush();
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
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)) {
|
if (!pilotOut.swap(count) || !dataOut.swap(count)) {
|
||||||
bufMtx.unlock();
|
bufMtx.unlock();
|
||||||
@ -98,10 +98,9 @@ namespace dsp {
|
|||||||
complex_t* buffer;
|
complex_t* buffer;
|
||||||
int tapCount;
|
int tapCount;
|
||||||
complex_t* taps;
|
complex_t* taps;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FMStereoDemux: public generic_block<FMStereoDemux> {
|
class FMStereoDemux : public generic_block<FMStereoDemux> {
|
||||||
public:
|
public:
|
||||||
FMStereoDemux() {}
|
FMStereoDemux() {}
|
||||||
|
|
||||||
@ -163,18 +162,22 @@ namespace dsp {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
// Double the VCO, then mix it with the input data.
|
// Double the VCO, then mix it with the input data.
|
||||||
// IMPORTANT: THERE SHOULDN'T BE A NEED FOR A GAIN HERE
|
// 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;
|
AminusBOut.writeBuf[i] = (_data->readBuf[i].re * doubledVCO.re) * 2.0f;
|
||||||
|
|
||||||
// Calculate the phase error estimation
|
// Calculate the phase error estimation
|
||||||
error = _pilot->readBuf[i].phase() - vcoPhase;
|
error = _pilot->readBuf[i].phase() - vcoPhase;
|
||||||
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; }
|
else if (error <= -3.1415926535f) {
|
||||||
|
error += 2.0f * 3.1415926535f;
|
||||||
|
}
|
||||||
|
|
||||||
// Integrate frequency and clamp it
|
// Integrate frequency and clamp it
|
||||||
vcoFrequency += _beta * error;
|
vcoFrequency += _beta * error;
|
||||||
if (vcoFrequency > upperLimit) { vcoFrequency = upperLimit; }
|
if (vcoFrequency > upperLimit) { vcoFrequency = upperLimit; }
|
||||||
else if (vcoFrequency < lowerLimit) { vcoFrequency = lowerLimit; }
|
else if (vcoFrequency < lowerLimit) {
|
||||||
|
vcoFrequency = lowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate new phase and wrap it
|
// Calculate new phase and wrap it
|
||||||
vcoPhase += vcoFrequency + (_alpha * error);
|
vcoPhase += vcoFrequency + (_alpha * error);
|
||||||
@ -207,7 +210,7 @@ namespace dsp {
|
|||||||
const float lowerLimit = ((18800.0f / 250000.0f) * 2.0f * FL_M_PI);
|
const float lowerLimit = ((18800.0f / 250000.0f) * 2.0f * FL_M_PI);
|
||||||
|
|
||||||
float _alpha; // Integral coefficient
|
float _alpha; // Integral coefficient
|
||||||
float _beta; // Proportional coefficient
|
float _beta; // Proportional coefficient
|
||||||
float vcoFrequency = expectedFreq;
|
float vcoFrequency = expectedFreq;
|
||||||
float vcoPhase = 0.0f;
|
float vcoPhase = 0.0f;
|
||||||
complex_t lastVCO;
|
complex_t lastVCO;
|
||||||
@ -284,6 +287,5 @@ namespace dsp {
|
|||||||
|
|
||||||
float* leftBuf;
|
float* leftBuf;
|
||||||
float* rightBuf;
|
float* rightBuf;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
#include <volk/volk.h>
|
#include <volk/volk.h>
|
||||||
|
|
||||||
// 1MB buffer
|
// 1MB buffer
|
||||||
#define STREAM_BUFFER_SIZE 1000000
|
#define STREAM_BUFFER_SIZE 1000000
|
||||||
|
|
||||||
namespace dsp {
|
namespace dsp {
|
||||||
class untyped_stream {
|
class untyped_stream {
|
||||||
@ -35,7 +35,7 @@ namespace dsp {
|
|||||||
{
|
{
|
||||||
// Wait to either swap or stop
|
// Wait to either swap or stop
|
||||||
std::unique_lock<std::mutex> lck(swapMtx);
|
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 writer was stopped, abandon operation
|
||||||
if (writerStop) { return false; }
|
if (writerStop) { return false; }
|
||||||
@ -61,7 +61,7 @@ namespace dsp {
|
|||||||
int read() {
|
int read() {
|
||||||
// Wait for data to be ready or to be stopped
|
// Wait for data to be ready or to be stopped
|
||||||
std::unique_lock<std::mutex> lck(rdyMtx);
|
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);
|
return (readerStop ? -1 : dataSize);
|
||||||
}
|
}
|
||||||
|
@ -5,27 +5,27 @@
|
|||||||
namespace dsp {
|
namespace dsp {
|
||||||
struct complex_t {
|
struct complex_t {
|
||||||
complex_t operator*(const float 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 float 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) {
|
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) {
|
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) {
|
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() {
|
inline complex_t conj() {
|
||||||
return complex_t{re, -im};
|
return complex_t{ re, -im };
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float phase() {
|
inline float phase() {
|
||||||
@ -36,7 +36,7 @@ namespace dsp {
|
|||||||
float abs_im = fabsf(im);
|
float abs_im = fabsf(im);
|
||||||
float r, angle;
|
float r, angle;
|
||||||
if (re == 0.0f && im == 0.0f) { return 0.0f; }
|
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);
|
r = (re - abs_im) / (re + abs_im);
|
||||||
angle = (FL_M_PI / 4.0f) - (FL_M_PI / 4.0f) * r;
|
angle = (FL_M_PI / 4.0f) - (FL_M_PI / 4.0f) * r;
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ namespace dsp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline float amplitude() {
|
inline float amplitude() {
|
||||||
return sqrt((re*re) + (im*im));
|
return sqrt((re * re) + (im * im));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float fastAmplitude() {
|
inline float fastAmplitude() {
|
||||||
@ -67,15 +67,15 @@ namespace dsp {
|
|||||||
|
|
||||||
struct stereo_t {
|
struct stereo_t {
|
||||||
stereo_t operator*(const float b) {
|
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) {
|
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) {
|
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;
|
float l;
|
||||||
|
@ -61,9 +61,9 @@ namespace dsp {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const uint32_t ASM_VALUE = 0x1ACFFC1D;
|
const uint32_t ASM_VALUE = 0x1ACFFC1D;
|
||||||
const uint8_t ASM_BYTES[4] = {0x1A, 0xCF, 0xFC, 0x1D};
|
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_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_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 {
|
class FrameDataDecoder {
|
||||||
public:
|
public:
|
||||||
@ -109,11 +109,10 @@ namespace dsp {
|
|||||||
bool _dualBasis;
|
bool _dualBasis;
|
||||||
int _rsBlockSize;
|
int _rsBlockSize;
|
||||||
int _rsParitySize;
|
int _rsParitySize;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void descramble(uint8_t* in, uint8_t* out, int count) {
|
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];
|
out[i] = in[i] ^ SCRAMBLING_SEQUENCE[i % 255];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <dsp/types.h>
|
#include <dsp/types.h>
|
||||||
|
|
||||||
#define DSP_SIGN(n) ((n) >= 0)
|
#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_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_STEP(n) (((n) > 0.0f) ? 1.0f : -1.0f)
|
@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define FL_M_PI 3.1415926535f
|
#define FL_M_PI 3.1415926535f
|
||||||
|
|
||||||
namespace dsp {
|
namespace dsp {
|
||||||
namespace math {
|
namespace math {
|
||||||
inline double sinc(double omega, double x, double norm) {
|
inline double sinc(double omega, double x, double norm) {
|
||||||
return (x == 0.0f) ? 1.0f : (sin(omega*x)/(norm*x));
|
return (x == 0.0f) ? 1.0f : (sin(omega * x) / (norm * x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,13 +4,13 @@
|
|||||||
namespace dsp {
|
namespace dsp {
|
||||||
namespace window_function {
|
namespace window_function {
|
||||||
inline double blackman(double n, double N, double alpha = 0.16f) {
|
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;
|
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) {
|
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) {
|
inline double nuttall(double n, double N) {
|
||||||
|
@ -60,7 +60,10 @@ namespace dsp {
|
|||||||
void setInSampleRate(float inSampleRate) {
|
void setInSampleRate(float inSampleRate) {
|
||||||
assert(_init);
|
assert(_init);
|
||||||
_inSampleRate = inSampleRate;
|
_inSampleRate = inSampleRate;
|
||||||
if (running) { xlator.stop(); resamp.stop(); }
|
if (running) {
|
||||||
|
xlator.stop();
|
||||||
|
resamp.stop();
|
||||||
|
}
|
||||||
xlator.setSampleRate(_inSampleRate);
|
xlator.setSampleRate(_inSampleRate);
|
||||||
resamp.setInSampleRate(_inSampleRate);
|
resamp.setInSampleRate(_inSampleRate);
|
||||||
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
|
float realCutoff = std::min<float>(_bandWidth, std::min<float>(_inSampleRate, _outSampleRate)) / 2.0f;
|
||||||
@ -68,7 +71,10 @@ namespace dsp {
|
|||||||
win.setCutoff(realCutoff);
|
win.setCutoff(realCutoff);
|
||||||
win.setTransWidth(realCutoff);
|
win.setTransWidth(realCutoff);
|
||||||
resamp.updateWindow(&win);
|
resamp.updateWindow(&win);
|
||||||
if (running) { xlator.start(); resamp.start(); }
|
if (running) {
|
||||||
|
xlator.start();
|
||||||
|
resamp.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOutSampleRate(float outSampleRate) {
|
void setOutSampleRate(float outSampleRate) {
|
||||||
@ -123,6 +129,5 @@ namespace dsp {
|
|||||||
stream<complex_t>* _in;
|
stream<complex_t>* _in;
|
||||||
FrequencyXlator<complex_t> xlator;
|
FrequencyXlator<complex_t> xlator;
|
||||||
PolyphaseResampler<complex_t> resamp;
|
PolyphaseResampler<complex_t> resamp;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -67,7 +67,7 @@ namespace dsp {
|
|||||||
float sum = 0.0f;
|
float sum = 0.0f;
|
||||||
float tc = tapCount;
|
float tc = tapCount;
|
||||||
for (int i = 0; i < tapCount; i++) {
|
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;
|
taps[i] = val;
|
||||||
sum += val;
|
sum += val;
|
||||||
}
|
}
|
||||||
@ -81,7 +81,6 @@ namespace dsp {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
float _cutoff, _transWidth, _sampleRate;
|
float _cutoff, _transWidth, _sampleRate;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BandPassBlackmanWindow : public filter_window::generic_complex_window {
|
class BandPassBlackmanWindow : public filter_window::generic_complex_window {
|
||||||
@ -163,7 +162,7 @@ namespace dsp {
|
|||||||
float sum = 0.0f;
|
float sum = 0.0f;
|
||||||
float tc = tapCount;
|
float tc = tapCount;
|
||||||
for (int i = 0; i < tapCount; i++) {
|
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].re = val;
|
||||||
taps[i].im = 0;
|
taps[i].im = 0;
|
||||||
sum += val;
|
sum += val;
|
||||||
@ -225,26 +224,24 @@ namespace dsp {
|
|||||||
|
|
||||||
double spb = _sampleRate / _baudRate; // samples per bit/symbol
|
double spb = _sampleRate / _baudRate; // samples per bit/symbol
|
||||||
double scale = 0;
|
double scale = 0;
|
||||||
for (int i = 0; i < tapCount; i++)
|
for (int i = 0; i < tapCount; i++) {
|
||||||
{
|
|
||||||
double x1, x2, x3, num, den;
|
double x1, x2, x3, num, den;
|
||||||
double xindx = i - tapCount / 2;
|
double xindx = i - tapCount / 2;
|
||||||
x1 = FL_M_PI * xindx / spb;
|
x1 = FL_M_PI * xindx / spb;
|
||||||
x2 = 4 * _alpha * xindx / spb;
|
x2 = 4 * _alpha * xindx / spb;
|
||||||
x3 = x2 * x2 - 1;
|
x3 = x2 * x2 - 1;
|
||||||
|
|
||||||
// Avoid Rounding errors...
|
// Avoid Rounding errors...
|
||||||
if (fabs(x3) >= 0.000001) {
|
if (fabs(x3) >= 0.000001) {
|
||||||
if (i != tapCount / 2)
|
if (i != tapCount / 2)
|
||||||
num = cos((1 + _alpha) * x1) +
|
num = cos((1 + _alpha) * x1) +
|
||||||
sin((1 - _alpha) * x1) / (4 * _alpha * xindx / spb);
|
sin((1 - _alpha) * x1) / (4 * _alpha * xindx / spb);
|
||||||
else
|
else
|
||||||
num = cos((1 + _alpha) * x1) + (1 - _alpha) * FL_M_PI / (4 * _alpha);
|
num = cos((1 + _alpha) * x1) + (1 - _alpha) * FL_M_PI / (4 * _alpha);
|
||||||
den = x3 * FL_M_PI;
|
den = x3 * FL_M_PI;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (_alpha == 1)
|
if (_alpha == 1) {
|
||||||
{
|
|
||||||
taps[i] = -1;
|
taps[i] = -1;
|
||||||
scale += taps[i];
|
scale += taps[i];
|
||||||
continue;
|
continue;
|
||||||
@ -252,8 +249,8 @@ namespace dsp {
|
|||||||
x3 = (1 - _alpha) * x1;
|
x3 = (1 - _alpha) * x1;
|
||||||
x2 = (1 + _alpha) * x1;
|
x2 = (1 + _alpha) * x1;
|
||||||
num = (sin(x2) * (1 + _alpha) * FL_M_PI -
|
num = (sin(x2) * (1 + _alpha) * FL_M_PI -
|
||||||
cos(x3) * ((1 - _alpha) * FL_M_PI * spb) / (4 * _alpha * xindx) +
|
cos(x3) * ((1 - _alpha) * FL_M_PI * spb) / (4 * _alpha * xindx) +
|
||||||
sin(x3) * spb * spb / (4 * _alpha * xindx * xindx));
|
sin(x3) * spb * spb / (4 * _alpha * xindx * xindx));
|
||||||
den = -32 * FL_M_PI * _alpha * _alpha * xindx / spb;
|
den = -32 * FL_M_PI * _alpha * _alpha * xindx / spb;
|
||||||
}
|
}
|
||||||
taps[i] = 4 * _alpha * num / den;
|
taps[i] = 4 * _alpha * num / den;
|
||||||
@ -268,7 +265,6 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
int _tapCount;
|
int _tapCount;
|
||||||
float _sampleRate, _baudRate, _alpha;
|
float _sampleRate, _baudRate, _alpha;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// class NotchWindow : public filter_window::generic_complex_window {
|
// class NotchWindow : public filter_window::generic_complex_window {
|
||||||
@ -407,7 +403,7 @@ namespace dsp {
|
|||||||
// Generate exponential decay
|
// Generate exponential decay
|
||||||
float fact = 1.0f / (float)tapCount;
|
float fact = 1.0f / (float)tapCount;
|
||||||
for (int i = 0; i < tapCount; i++) {
|
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
|
// Frequency translate it to the right place
|
||||||
@ -419,6 +415,5 @@ namespace dsp {
|
|||||||
private:
|
private:
|
||||||
float _frequency, _sampleRate;
|
float _frequency, _sampleRate;
|
||||||
int _tapCount;
|
int _tapCount;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -36,7 +36,7 @@ namespace colormaps {
|
|||||||
map.entryCount = mapTxt.size();
|
map.entryCount = mapTxt.size();
|
||||||
map.map = new float[mapTxt.size() * 3];
|
map.map = new float[mapTxt.size() * 3];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(auto const& col : mapTxt) {
|
for (auto const& col : mapTxt) {
|
||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
map.map[i * 3] = std::stoi(col.substr(1, 2), NULL, 16);
|
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);
|
map.map[(i * 3) + 1] = std::stoi(col.substr(3, 2), NULL, 16);
|
||||||
|
@ -10,14 +10,13 @@ namespace credits {
|
|||||||
ImFont* bigFont;
|
ImFont* bigFont;
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void show() {
|
void show() {
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 20.0f));
|
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 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::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||||
ImGui::OpenPopup("Credits");
|
ImGui::OpenPopup("Credits");
|
||||||
ImGui::BeginPopupModal("Credits", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);
|
ImGui::BeginPopupModal("Credits", NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);
|
||||||
|
@ -4,19 +4,19 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
|
|
||||||
#define GENERIC_DIALOG_BUTTONS_OK "Ok\0"
|
#define GENERIC_DIALOG_BUTTONS_OK "Ok\0"
|
||||||
#define GENERIC_DIALOG_BUTTONS_YES_NO "Yes\0No\0"
|
#define GENERIC_DIALOG_BUTTONS_YES_NO "Yes\0No\0"
|
||||||
#define GENERIC_DIALOG_BUTTONS_APPLY_CANCEL "Apply\0Cancel\0"
|
#define GENERIC_DIALOG_BUTTONS_APPLY_CANCEL "Apply\0Cancel\0"
|
||||||
#define GENERIC_DIALOG_BUTTONS_OK_CANCEL "Ok\0Cancel\0"
|
#define GENERIC_DIALOG_BUTTONS_OK_CANCEL "Ok\0Cancel\0"
|
||||||
|
|
||||||
#define GENERIC_DIALOG_BUTTON_OK 0
|
#define GENERIC_DIALOG_BUTTON_OK 0
|
||||||
#define GENERIC_DIALOG_BUTTON_YES 0
|
#define GENERIC_DIALOG_BUTTON_YES 0
|
||||||
#define GENERIC_DIALOG_BUTTON_NO 1
|
#define GENERIC_DIALOG_BUTTON_NO 1
|
||||||
#define GENERIC_DIALOG_BUTTON_APPLY 0
|
#define GENERIC_DIALOG_BUTTON_APPLY 0
|
||||||
#define GENERIC_DIALOG_BUTTON_CANCE 1
|
#define GENERIC_DIALOG_BUTTON_CANCE 1
|
||||||
|
|
||||||
namespace ImGui {
|
namespace ImGui {
|
||||||
template<typename Func>
|
template <typename Func>
|
||||||
int GenericDialog(const char* id, bool& open, const char* buttons, Func draw) {
|
int GenericDialog(const char* id, bool& open, const char* buttons, Func draw) {
|
||||||
// If not open, return
|
// If not open, return
|
||||||
if (!open) { return -1; }
|
if (!open) { return -1; }
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,7 +20,7 @@ namespace icons {
|
|||||||
ImTextureID CENTER_TUNING;
|
ImTextureID CENTER_TUNING;
|
||||||
|
|
||||||
GLuint loadTexture(std::string path) {
|
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);
|
stbi_uc* data = stbi_load(path.c_str(), &w, &h, &n, 0);
|
||||||
GLuint texId;
|
GLuint texId;
|
||||||
glGenTextures(1, &texId);
|
glGenTextures(1, &texId);
|
||||||
|
@ -49,10 +49,22 @@ void MainWindow::init() {
|
|||||||
// Load menu elements
|
// Load menu elements
|
||||||
gui::menu.order.clear();
|
gui::menu.order.clear();
|
||||||
for (auto& elem : menuElements) {
|
for (auto& elem : menuElements) {
|
||||||
if (!elem.contains("name")) { spdlog::error("Menu element is missing name key"); continue; }
|
if (!elem.contains("name")) {
|
||||||
if (!elem["name"].is_string()) { spdlog::error("Menu element name isn't a string"); continue; }
|
spdlog::error("Menu element is missing name key");
|
||||||
if (!elem.contains("open")) { spdlog::error("Menu element is missing open key"); continue; }
|
continue;
|
||||||
if (!elem["open"].is_boolean()) { spdlog::error("Menu element name isn't a string"); 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;
|
Menu::MenuOption_t opt;
|
||||||
opt.name = elem["name"];
|
opt.name = elem["name"];
|
||||||
opt.open = elem["open"];
|
opt.open = elem["open"];
|
||||||
@ -73,8 +85,8 @@ void MainWindow::init() {
|
|||||||
gui::waterfall.setBandwidth(8000000);
|
gui::waterfall.setBandwidth(8000000);
|
||||||
gui::waterfall.setViewBandwidth(8000000);
|
gui::waterfall.setViewBandwidth(8000000);
|
||||||
|
|
||||||
fft_in = (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);
|
fft_out = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
||||||
fftwPlan = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
|
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);
|
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
|
// Load modules from /module directory
|
||||||
if (std::filesystem::is_directory(modulesDir)) {
|
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();
|
std::string path = file.path().generic_string();
|
||||||
if (file.path().extension().generic_string() != SDRPP_MOD_EXTENTSION) {
|
if (file.path().extension().generic_string() != SDRPP_MOD_EXTENTSION) {
|
||||||
continue;
|
continue;
|
||||||
@ -130,7 +142,7 @@ void MainWindow::init() {
|
|||||||
LoadingScreen::show("Loading color maps");
|
LoadingScreen::show("Loading color maps");
|
||||||
spdlog::info("Loading color maps");
|
spdlog::info("Loading color maps");
|
||||||
if (std::filesystem::is_directory(resourcesDir + "/colormaps")) {
|
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();
|
std::string path = file.path().generic_string();
|
||||||
LoadingScreen::show("Loading " + path);
|
LoadingScreen::show("Loading " + path);
|
||||||
spdlog::info("Loading {0}", path);
|
spdlog::info("Loading {0}", path);
|
||||||
@ -196,11 +208,11 @@ void MainWindow::init() {
|
|||||||
float finalBwHalf = gui::waterfall.getBandwidth() / 2.0;
|
float finalBwHalf = gui::waterfall.getBandwidth() / 2.0;
|
||||||
for (auto& [_name, _vfo] : gui::waterfall.vfos) {
|
for (auto& [_name, _vfo] : gui::waterfall.vfos) {
|
||||||
if (_vfo->lowerOffset < -finalBwHalf) {
|
if (_vfo->lowerOffset < -finalBwHalf) {
|
||||||
sigpath::vfoManager.setCenterOffset(_name, (_vfo->bandwidth/2)-finalBwHalf);
|
sigpath::vfoManager.setCenterOffset(_name, (_vfo->bandwidth / 2) - finalBwHalf);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (_vfo->upperOffset > finalBwHalf) {
|
if (_vfo->upperOffset > finalBwHalf) {
|
||||||
sigpath::vfoManager.setCenterOffset(_name, finalBwHalf-(_vfo->bandwidth/2));
|
sigpath::vfoManager.setCenterOffset(_name, finalBwHalf - (_vfo->bandwidth / 2));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +236,7 @@ void MainWindow::fftHandler(dsp::complex_t* samples, int count, void* ctx) {
|
|||||||
|
|
||||||
// Zero out the rest of the samples
|
// Zero out the rest of the samples
|
||||||
if (count < _this->fftSize) {
|
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
|
// Execute FFT
|
||||||
@ -258,14 +270,12 @@ void MainWindow::vfoAddedHandler(VFOManager::VFO* vfo, void* ctx) {
|
|||||||
double viewBW = gui::waterfall.getViewBandwidth();
|
double viewBW = gui::waterfall.getViewBandwidth();
|
||||||
double viewOffset = gui::waterfall.getViewOffset();
|
double viewOffset = gui::waterfall.getViewOffset();
|
||||||
|
|
||||||
double viewLower = viewOffset - (viewBW/2.0);
|
double viewLower = viewOffset - (viewBW / 2.0);
|
||||||
double viewUpper = viewOffset + (viewBW/2.0);
|
double viewUpper = viewOffset + (viewBW / 2.0);
|
||||||
|
|
||||||
double newOffset = std::clamp<double>(offset, viewLower, viewUpper);
|
double newOffset = std::clamp<double>(offset, viewLower, viewUpper);
|
||||||
|
|
||||||
sigpath::vfoManager.setCenterOffset(name, _this->initComplete ? newOffset : offset);
|
sigpath::vfoManager.setCenterOffset(name, _this->initComplete ? newOffset : offset);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::draw() {
|
void MainWindow::draw() {
|
||||||
@ -415,7 +425,7 @@ void MainWindow::draw() {
|
|||||||
|
|
||||||
int snrWidth = std::min<int>(300, ImGui::GetWindowSize().x - ImGui::GetCursorPosX() - 87);
|
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::SetCursorPosY(ImGui::GetCursorPosY() + 5);
|
||||||
ImGui::SetNextItemWidth(snrWidth);
|
ImGui::SetNextItemWidth(snrWidth);
|
||||||
ImGui::SNRMeter((vfo != NULL) ? gui::waterfall.selectedVFOSNR : 0);
|
ImGui::SNRMeter((vfo != NULL) ? gui::waterfall.selectedVFOSNR : 0);
|
||||||
@ -456,7 +466,7 @@ void MainWindow::draw() {
|
|||||||
else {
|
else {
|
||||||
ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
|
ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
|
||||||
}
|
}
|
||||||
if(!down && grabbingMenu) {
|
if (!down && grabbingMenu) {
|
||||||
grabbingMenu = false;
|
grabbingMenu = false;
|
||||||
menuWidth = newWidth;
|
menuWidth = newWidth;
|
||||||
core::configManager.acquire();
|
core::configManager.acquire();
|
||||||
@ -500,7 +510,7 @@ void MainWindow::draw() {
|
|||||||
firstMenuRender = false;
|
firstMenuRender = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::CollapsingHeader("Debug")) {
|
if (ImGui::CollapsingHeader("Debug")) {
|
||||||
ImGui::Text("Frame time: %.3f ms/frame", 1000.0 / ImGui::GetIO().Framerate);
|
ImGui::Text("Frame time: %.3f ms/frame", 1000.0 / ImGui::GetIO().Framerate);
|
||||||
ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate);
|
ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate);
|
||||||
ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency());
|
ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency());
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <gui/tuner.h>
|
#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 {
|
class MainWindow {
|
||||||
public:
|
public:
|
||||||
@ -64,5 +64,4 @@ private:
|
|||||||
bool initComplete = false;
|
bool initComplete = false;
|
||||||
|
|
||||||
EventHandler<VFOManager::VFO*> vfoCreatedHandler;
|
EventHandler<VFOManager::VFO*> vfoCreatedHandler;
|
||||||
|
|
||||||
};
|
};
|
@ -21,7 +21,7 @@ namespace bandplanmenu {
|
|||||||
if (bandplan::bandplans.find(core::configManager.conf["bandPlan"]) != bandplan::bandplans.end()) {
|
if (bandplan::bandplans.find(core::configManager.conf["bandPlan"]) != bandplan::bandplans.end()) {
|
||||||
std::string name = core::configManager.conf["bandPlan"];
|
std::string name = core::configManager.conf["bandPlan"];
|
||||||
bandplanId = std::distance(bandplan::bandplanNames.begin(), std::find(bandplan::bandplanNames.begin(),
|
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];
|
gui::waterfall.bandplan = &bandplan::bandplans[name];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -33,15 +33,15 @@ namespace displaymenu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char* FFTSizesStr = "524288\0"
|
const char* FFTSizesStr = "524288\0"
|
||||||
"262144\0"
|
"262144\0"
|
||||||
"131072\0"
|
"131072\0"
|
||||||
"65536\0"
|
"65536\0"
|
||||||
"32768\0"
|
"32768\0"
|
||||||
"16384\0"
|
"16384\0"
|
||||||
"8192\0"
|
"8192\0"
|
||||||
"4096\0"
|
"4096\0"
|
||||||
"2048\0"
|
"2048\0"
|
||||||
"1024\0";
|
"1024\0";
|
||||||
|
|
||||||
int fftSizeId = 0;
|
int fftSizeId = 0;
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ namespace displaymenu {
|
|||||||
fftRate = core::configManager.conf["fftRate"];
|
fftRate = core::configManager.conf["fftRate"];
|
||||||
sigpath::signalPath.setFFTRate(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);
|
gui::mainWindow.setFFTWindow(selectedWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,5 @@ namespace displaymenu {
|
|||||||
}
|
}
|
||||||
ImGui::Text("Color map Author: %s", colorMapAuthor.c_str());
|
ImGui::Text("Color map Author: %s", colorMapAuthor.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -51,7 +51,7 @@ namespace module_manager_menu {
|
|||||||
ImGui::TableSetColumnIndex(2);
|
ImGui::TableSetColumnIndex(2);
|
||||||
ImVec2 origPos = ImGui::GetCursorPos();
|
ImVec2 origPos = ImGui::GetCursorPos();
|
||||||
ImGui::SetCursorPos(ImVec2(origPos.x - 3, origPos.y));
|
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;
|
toBeRemoved = name;
|
||||||
confirmOpened = true;
|
confirmOpened = true;
|
||||||
}
|
}
|
||||||
@ -61,14 +61,14 @@ namespace module_manager_menu {
|
|||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::GenericDialog("module_mgr_confirm_", confirmOpened, GENERIC_DIALOG_BUTTONS_YES_NO, [](){
|
if (ImGui::GenericDialog("module_mgr_confirm_", confirmOpened, GENERIC_DIALOG_BUTTONS_YES_NO, []() {
|
||||||
ImGui::Text("Deleting \"%s\". Are you sure?", toBeRemoved.c_str());
|
ImGui::Text("Deleting \"%s\". Are you sure?", toBeRemoved.c_str());
|
||||||
}) == GENERIC_DIALOG_BUTTON_YES) {
|
}) == GENERIC_DIALOG_BUTTON_YES) {
|
||||||
core::moduleManager.deleteInstance(toBeRemoved);
|
core::moduleManager.deleteInstance(toBeRemoved);
|
||||||
modified = true;
|
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());
|
ImGui::Text(errorMessage.c_str());
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ namespace module_manager_menu {
|
|||||||
|
|
||||||
ImGui::TableSetColumnIndex(2);
|
ImGui::TableSetColumnIndex(2);
|
||||||
if (strlen(modName) == 0) { style::beginDisabled(); }
|
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])) {
|
if (!core::moduleManager.createInstance(modName, modTypes[modTypeId])) {
|
||||||
core::moduleManager.postInit(modName);
|
core::moduleManager.postInit(modName);
|
||||||
modified = true;
|
modified = true;
|
||||||
|
@ -34,29 +34,41 @@ namespace sourecmenu {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char* offsetModesTxt = "None\0"
|
const char* offsetModesTxt = "None\0"
|
||||||
"Custom\0"
|
"Custom\0"
|
||||||
"SpyVerter\0"
|
"SpyVerter\0"
|
||||||
"Ham-It-Up\0"
|
"Ham-It-Up\0"
|
||||||
"DK5AV X-Band\0"
|
"DK5AV X-Band\0"
|
||||||
"Ku LNB (9750MHz)\0"
|
"Ku LNB (9750MHz)\0"
|
||||||
"Ku LNB (10700MHz)\0";
|
"Ku LNB (10700MHz)\0";
|
||||||
|
|
||||||
const char* decimationStages = "None\0"
|
const char* decimationStages = "None\0"
|
||||||
"2\0"
|
"2\0"
|
||||||
"4\0"
|
"4\0"
|
||||||
"8\0"
|
"8\0"
|
||||||
"16\0"
|
"16\0"
|
||||||
"32\0"
|
"32\0"
|
||||||
"64\0";
|
"64\0";
|
||||||
|
|
||||||
void updateOffset() {
|
void updateOffset() {
|
||||||
if (offsetMode == OFFSET_MODE_CUSTOM) { effectiveOffset = customOffset; }
|
if (offsetMode == OFFSET_MODE_CUSTOM) { effectiveOffset = customOffset; }
|
||||||
else if (offsetMode == OFFSET_MODE_SPYVERTER) { effectiveOffset = 120000000; } // 120MHz Up-conversion
|
else if (offsetMode == OFFSET_MODE_SPYVERTER) {
|
||||||
else if (offsetMode == OFFSET_MODE_HAM_IT_UP) { effectiveOffset = 125000000; } // 125MHz Up-conversion
|
effectiveOffset = 120000000;
|
||||||
else if (offsetMode == OFFSET_MODE_DK5AV_XB) { effectiveOffset = -6800000000; } // 6.8GHz Down-conversion
|
} // 120MHz Up-conversion
|
||||||
else if (offsetMode == OFFSET_MODE_KU_LNB_9750) { effectiveOffset = -9750000000; } // 9.750GHz Down-conversion
|
else if (offsetMode == OFFSET_MODE_HAM_IT_UP) {
|
||||||
else if (offsetMode == OFFSET_MODE_KU_LNB_10700) { effectiveOffset = -10700000000; } // 10.7GHz Down-conversion
|
effectiveOffset = 125000000;
|
||||||
else { effectiveOffset = 0; }
|
} // 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);
|
sigpath::sourceManager.setTuningOffset(effectiveOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ namespace vfo_color_menu {
|
|||||||
if (vfoColors.find(name) != vfoColors.end()) {
|
if (vfoColors.find(name) != vfoColors.end()) {
|
||||||
col = vfoColors[name];
|
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;
|
vfoColors[name] = col;
|
||||||
vfo->color = IM_COL32((int)roundf(col.x * 255), (int)roundf(col.y * 255), (int)roundf(col.z * 255), 50);
|
vfo->color = IM_COL32((int)roundf(col.x * 255), (int)roundf(col.y * 255), (int)roundf(col.z * 255), 50);
|
||||||
core::configManager.acquire();
|
core::configManager.acquire();
|
||||||
|
@ -27,7 +27,7 @@ bool ThemeManager::loadThemesFromDir(std::string path) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
themes.clear();
|
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();
|
std::string _path = file.path().generic_string();
|
||||||
if (file.path().extension().generic_string() != ".json") {
|
if (file.path().extension().generic_string() != ".json") {
|
||||||
continue;
|
continue;
|
||||||
@ -142,20 +142,20 @@ bool ThemeManager::applyTheme(std::string name) {
|
|||||||
|
|
||||||
if (param == "WaterfallBackground") {
|
if (param == "WaterfallBackground") {
|
||||||
decodeRGBA(val, ret);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param == "ClearColor") {
|
if (param == "ClearColor") {
|
||||||
decodeRGBA(val, ret);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If param is a color, check that it's a valid RGBA hex value
|
// If param is a color, check that it's a valid RGBA hex value
|
||||||
if (IMGUI_COL_IDS.find(param) != IMGUI_COL_IDS.end()) {
|
if (IMGUI_COL_IDS.find(param) != IMGUI_COL_IDS.end()) {
|
||||||
decodeRGBA(val, ret);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,57 +181,57 @@ std::vector<std::string> ThemeManager::getThemeNames() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, int> ThemeManager::IMGUI_COL_IDS = {
|
std::map<std::string, int> ThemeManager::IMGUI_COL_IDS = {
|
||||||
{"Text", ImGuiCol_Text},
|
{ "Text", ImGuiCol_Text },
|
||||||
{"TextDisabled", ImGuiCol_TextDisabled},
|
{ "TextDisabled", ImGuiCol_TextDisabled },
|
||||||
{"WindowBg", ImGuiCol_WindowBg},
|
{ "WindowBg", ImGuiCol_WindowBg },
|
||||||
{"ChildBg", ImGuiCol_ChildBg},
|
{ "ChildBg", ImGuiCol_ChildBg },
|
||||||
{"PopupBg", ImGuiCol_PopupBg},
|
{ "PopupBg", ImGuiCol_PopupBg },
|
||||||
{"Border", ImGuiCol_Border},
|
{ "Border", ImGuiCol_Border },
|
||||||
{"BorderShadow", ImGuiCol_BorderShadow},
|
{ "BorderShadow", ImGuiCol_BorderShadow },
|
||||||
{"FrameBg", ImGuiCol_FrameBg},
|
{ "FrameBg", ImGuiCol_FrameBg },
|
||||||
{"FrameBgHovered", ImGuiCol_FrameBgHovered},
|
{ "FrameBgHovered", ImGuiCol_FrameBgHovered },
|
||||||
{"FrameBgActive", ImGuiCol_FrameBgActive},
|
{ "FrameBgActive", ImGuiCol_FrameBgActive },
|
||||||
{"TitleBg", ImGuiCol_TitleBg},
|
{ "TitleBg", ImGuiCol_TitleBg },
|
||||||
{"TitleBgActive", ImGuiCol_TitleBgActive},
|
{ "TitleBgActive", ImGuiCol_TitleBgActive },
|
||||||
{"TitleBgCollapsed", ImGuiCol_TitleBgCollapsed},
|
{ "TitleBgCollapsed", ImGuiCol_TitleBgCollapsed },
|
||||||
{"MenuBarBg", ImGuiCol_MenuBarBg},
|
{ "MenuBarBg", ImGuiCol_MenuBarBg },
|
||||||
{"ScrollbarBg", ImGuiCol_ScrollbarBg},
|
{ "ScrollbarBg", ImGuiCol_ScrollbarBg },
|
||||||
{"ScrollbarGrab", ImGuiCol_ScrollbarGrab},
|
{ "ScrollbarGrab", ImGuiCol_ScrollbarGrab },
|
||||||
{"ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered},
|
{ "ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered },
|
||||||
{"ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive},
|
{ "ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive },
|
||||||
{"CheckMark", ImGuiCol_CheckMark},
|
{ "CheckMark", ImGuiCol_CheckMark },
|
||||||
{"SliderGrab", ImGuiCol_SliderGrab},
|
{ "SliderGrab", ImGuiCol_SliderGrab },
|
||||||
{"SliderGrabActive", ImGuiCol_SliderGrabActive},
|
{ "SliderGrabActive", ImGuiCol_SliderGrabActive },
|
||||||
{"Button", ImGuiCol_Button},
|
{ "Button", ImGuiCol_Button },
|
||||||
{"ButtonHovered", ImGuiCol_ButtonHovered},
|
{ "ButtonHovered", ImGuiCol_ButtonHovered },
|
||||||
{"ButtonActive", ImGuiCol_ButtonActive},
|
{ "ButtonActive", ImGuiCol_ButtonActive },
|
||||||
{"Header", ImGuiCol_Header},
|
{ "Header", ImGuiCol_Header },
|
||||||
{"HeaderHovered", ImGuiCol_HeaderHovered},
|
{ "HeaderHovered", ImGuiCol_HeaderHovered },
|
||||||
{"HeaderActive", ImGuiCol_HeaderActive},
|
{ "HeaderActive", ImGuiCol_HeaderActive },
|
||||||
{"Separator", ImGuiCol_Separator},
|
{ "Separator", ImGuiCol_Separator },
|
||||||
{"SeparatorHovered", ImGuiCol_SeparatorHovered},
|
{ "SeparatorHovered", ImGuiCol_SeparatorHovered },
|
||||||
{"SeparatorActive", ImGuiCol_SeparatorActive},
|
{ "SeparatorActive", ImGuiCol_SeparatorActive },
|
||||||
{"ResizeGrip", ImGuiCol_ResizeGrip},
|
{ "ResizeGrip", ImGuiCol_ResizeGrip },
|
||||||
{"ResizeGripHovered", ImGuiCol_ResizeGripHovered},
|
{ "ResizeGripHovered", ImGuiCol_ResizeGripHovered },
|
||||||
{"ResizeGripActive", ImGuiCol_ResizeGripActive},
|
{ "ResizeGripActive", ImGuiCol_ResizeGripActive },
|
||||||
{"Tab", ImGuiCol_Tab},
|
{ "Tab", ImGuiCol_Tab },
|
||||||
{"TabHovered", ImGuiCol_TabHovered},
|
{ "TabHovered", ImGuiCol_TabHovered },
|
||||||
{"TabActive", ImGuiCol_TabActive},
|
{ "TabActive", ImGuiCol_TabActive },
|
||||||
{"TabUnfocused", ImGuiCol_TabUnfocused},
|
{ "TabUnfocused", ImGuiCol_TabUnfocused },
|
||||||
{"TabUnfocusedActive", ImGuiCol_TabUnfocusedActive},
|
{ "TabUnfocusedActive", ImGuiCol_TabUnfocusedActive },
|
||||||
{"PlotLines", ImGuiCol_PlotLines},
|
{ "PlotLines", ImGuiCol_PlotLines },
|
||||||
{"PlotLinesHovered", ImGuiCol_PlotLinesHovered},
|
{ "PlotLinesHovered", ImGuiCol_PlotLinesHovered },
|
||||||
{"PlotHistogram", ImGuiCol_PlotHistogram},
|
{ "PlotHistogram", ImGuiCol_PlotHistogram },
|
||||||
{"PlotHistogramHovered", ImGuiCol_PlotHistogramHovered},
|
{ "PlotHistogramHovered", ImGuiCol_PlotHistogramHovered },
|
||||||
{"TableHeaderBg", ImGuiCol_TableHeaderBg},
|
{ "TableHeaderBg", ImGuiCol_TableHeaderBg },
|
||||||
{"TableBorderStrong", ImGuiCol_TableBorderStrong},
|
{ "TableBorderStrong", ImGuiCol_TableBorderStrong },
|
||||||
{"TableBorderLight", ImGuiCol_TableBorderLight},
|
{ "TableBorderLight", ImGuiCol_TableBorderLight },
|
||||||
{"TableRowBg", ImGuiCol_TableRowBg},
|
{ "TableRowBg", ImGuiCol_TableRowBg },
|
||||||
{"TableRowBgAlt", ImGuiCol_TableRowBgAlt},
|
{ "TableRowBgAlt", ImGuiCol_TableRowBgAlt },
|
||||||
{"TextSelectedBg", ImGuiCol_TextSelectedBg},
|
{ "TextSelectedBg", ImGuiCol_TextSelectedBg },
|
||||||
{"DragDropTarget", ImGuiCol_DragDropTarget},
|
{ "DragDropTarget", ImGuiCol_DragDropTarget },
|
||||||
{"NavHighlight", ImGuiCol_NavHighlight},
|
{ "NavHighlight", ImGuiCol_NavHighlight },
|
||||||
{"NavWindowingHighlight", ImGuiCol_NavWindowingHighlight},
|
{ "NavWindowingHighlight", ImGuiCol_NavWindowingHighlight },
|
||||||
{"NavWindowingDimBg", ImGuiCol_NavWindowingDimBg},
|
{ "NavWindowingDimBg", ImGuiCol_NavWindowingDimBg },
|
||||||
{"ModalWindowDimBg", ImGuiCol_ModalWindowDimBg}
|
{ "ModalWindowDimBg", ImGuiCol_ModalWindowDimBg }
|
||||||
};
|
};
|
@ -20,7 +20,8 @@ public:
|
|||||||
|
|
||||||
std::vector<std::string> getThemeNames();
|
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);
|
ImVec4 clearColor = ImVec4(0.0666f, 0.0666f, 0.0666f, 1.0f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -29,5 +30,4 @@ private:
|
|||||||
static std::map<std::string, int> IMGUI_COL_IDS;
|
static std::map<std::string, int> IMGUI_COL_IDS;
|
||||||
|
|
||||||
std::map<std::string, Theme> themes;
|
std::map<std::string, Theme> themes;
|
||||||
|
|
||||||
};
|
};
|
@ -31,7 +31,7 @@ namespace tuner {
|
|||||||
|
|
||||||
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[vfoName];
|
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[vfoName];
|
||||||
|
|
||||||
double currentOff = vfo->centerOffset;
|
double currentOff = vfo->centerOffset;
|
||||||
double currentTune = gui::waterfall.getCenterFrequency() + vfo->generalOffset;
|
double currentTune = gui::waterfall.getCenterFrequency() + vfo->generalOffset;
|
||||||
double delta = freq - currentTune;
|
double delta = freq - currentTune;
|
||||||
|
|
||||||
@ -119,21 +119,21 @@ namespace tuner {
|
|||||||
|
|
||||||
void tune(int mode, std::string vfoName, double freq) {
|
void tune(int mode, std::string vfoName, double freq) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case TUNER_MODE_CENTER:
|
case TUNER_MODE_CENTER:
|
||||||
centerTuning(vfoName, freq);
|
centerTuning(vfoName, freq);
|
||||||
break;
|
break;
|
||||||
case TUNER_MODE_NORMAL:
|
case TUNER_MODE_NORMAL:
|
||||||
normalTuning(vfoName, freq);
|
normalTuning(vfoName, freq);
|
||||||
break;
|
break;
|
||||||
case TUNER_MODE_LOWER_HALF:
|
case TUNER_MODE_LOWER_HALF:
|
||||||
normalTuning(vfoName, freq);
|
normalTuning(vfoName, freq);
|
||||||
break;
|
break;
|
||||||
case TUNER_MODE_UPPER_HALF:
|
case TUNER_MODE_UPPER_HALF:
|
||||||
normalTuning(vfoName, freq);
|
normalTuning(vfoName, freq);
|
||||||
break;
|
break;
|
||||||
case TUNER_MODE_IQ_ONLY:
|
case TUNER_MODE_IQ_ONLY:
|
||||||
iqTuning(freq);
|
iqTuning(freq);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,10 +21,10 @@ namespace bandplan {
|
|||||||
|
|
||||||
void to_json(json& j, const Band_t& b) {
|
void to_json(json& j, const Band_t& b) {
|
||||||
j = json{
|
j = json{
|
||||||
{"name", b.name},
|
{ "name", b.name },
|
||||||
{"type", b.type},
|
{ "type", b.type },
|
||||||
{"start", b.start},
|
{ "start", b.start },
|
||||||
{"end", b.end},
|
{ "end", b.end },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,12 +37,12 @@ namespace bandplan {
|
|||||||
|
|
||||||
void to_json(json& j, const BandPlan_t& b) {
|
void to_json(json& j, const BandPlan_t& b) {
|
||||||
j = json{
|
j = json{
|
||||||
{"name", b.name},
|
{ "name", b.name },
|
||||||
{"country_name", b.countryName},
|
{ "country_name", b.countryName },
|
||||||
{"country_code", b.countryCode},
|
{ "country_code", b.countryCode },
|
||||||
{"author_name", b.authorName},
|
{ "author_name", b.authorName },
|
||||||
{"author_url", b.authorURL},
|
{ "author_url", b.authorURL },
|
||||||
{"bands", b.bands}
|
{ "bands", b.bands }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ namespace bandplan {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bandplans.clear();
|
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();
|
std::string path = file.path().generic_string();
|
||||||
if (file.path().extension().generic_string() != ".json") {
|
if (file.path().extension().generic_string() != ".json") {
|
||||||
continue;
|
continue;
|
||||||
|
@ -12,7 +12,7 @@ namespace ImGui {
|
|||||||
float pad = style.FramePadding.y;
|
float pad = style.FramePadding.y;
|
||||||
ImVec2 min = window->DC.CursorPos;
|
ImVec2 min = window->DC.CursorPos;
|
||||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), CalcItemWidth());
|
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;
|
float lineHeight = size.y;
|
||||||
|
|
||||||
ItemSize(size, style.FramePadding.y);
|
ItemSize(size, style.FramePadding.y);
|
||||||
@ -20,13 +20,13 @@ namespace ImGui {
|
|||||||
return;
|
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 col = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
|
||||||
float increment = size.x / 1024.0f;
|
float increment = size.x / 1024.0f;
|
||||||
for (int i = 0; i < 1024; i++) {
|
for (int i = 0; i < 1024; i++) {
|
||||||
if (buffer[i].re > 1.5f || buffer[i].re < -1.5f) { continue; }
|
if (buffer[i].re > 1.5f || buffer[i].re < -1.5f) { continue; }
|
||||||
if (buffer[i].im > 1.5f || buffer[i].im < -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,5 @@ namespace ImGui {
|
|||||||
private:
|
private:
|
||||||
std::mutex bufferMtx;
|
std::mutex bufferMtx;
|
||||||
dsp::complex_t buffer[1024];
|
dsp::complex_t buffer[1024];
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -63,15 +63,15 @@ bool FileSelect::pathIsValid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FileSelect::worker() {
|
void FileSelect::worker() {
|
||||||
auto file = pfd::open_file("Open File", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "", _filter);
|
auto file = pfd::open_file("Open File", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "", _filter);
|
||||||
std::vector<std::string> res = file.result();
|
std::vector<std::string> res = file.result();
|
||||||
|
|
||||||
if (res.size() > 0) {
|
if (res.size() > 0) {
|
||||||
path = res[0];
|
path = res[0];
|
||||||
strcpy(strPath, path.c_str());
|
strcpy(strPath, path.c_str());
|
||||||
pathChanged = true;
|
pathChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pathValid = std::filesystem::is_regular_file(expandString(path));
|
pathValid = std::filesystem::is_regular_file(expandString(path));
|
||||||
dialogOpen = false;
|
dialogOpen = false;
|
||||||
}
|
}
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
class FileSelect {
|
class FileSelect {
|
||||||
public:
|
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);
|
bool render(std::string id);
|
||||||
void setPath(std::string path, bool markChanged = false);
|
void setPath(std::string path, bool markChanged = false);
|
||||||
bool pathIsValid();
|
bool pathIsValid();
|
||||||
|
@ -62,15 +62,15 @@ bool FolderSelect::pathIsValid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FolderSelect::worker() {
|
void FolderSelect::worker() {
|
||||||
auto fold = pfd::select_folder("Select Folder", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "");
|
auto fold = pfd::select_folder("Select Folder", pathValid ? std::filesystem::path(expandString(path)).parent_path().string() : "");
|
||||||
std::string res = fold.result();
|
std::string res = fold.result();
|
||||||
|
|
||||||
if (res != "") {
|
if (res != "") {
|
||||||
path = res;
|
path = res;
|
||||||
strcpy(strPath, path.c_str());
|
strcpy(strPath, path.c_str());
|
||||||
pathChanged = true;
|
pathChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pathValid = std::filesystem::is_directory(expandString(path));
|
pathValid = std::filesystem::is_directory(expandString(path));
|
||||||
dialogOpen = false;
|
dialogOpen = false;
|
||||||
}
|
}
|
@ -15,13 +15,11 @@ bool isInArea(ImVec2 val, ImVec2 min, ImVec2 max) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FrequencySelect::FrequencySelect() {
|
FrequencySelect::FrequencySelect() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrequencySelect::init() {
|
void FrequencySelect::init() {
|
||||||
for (int i = 0; i < 12; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
digits[i] = 0;
|
digits[i] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +43,6 @@ void FrequencySelect::onPosChange() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FrequencySelect::onResize() {
|
void FrequencySelect::onResize() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrequencySelect::incrementDigit(int i) {
|
void FrequencySelect::incrementDigit(int i) {
|
||||||
@ -135,11 +132,11 @@ void FrequencySelect::draw() {
|
|||||||
}
|
}
|
||||||
sprintf(buf, "%d", digits[i]);
|
sprintf(buf, "%d", digits[i]);
|
||||||
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset, widgetPos.y),
|
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) {
|
if ((i + 1) % 3 == 0 && i < 11) {
|
||||||
commaOffset += commaSz.x;
|
commaOffset += commaSz.x;
|
||||||
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + 11, widgetPos.y),
|
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + 11, widgetPos.y),
|
||||||
zeros ? disabledColor : textColor, ".");
|
zeros ? disabledColor : textColor, ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace ImGui {
|
|||||||
float height = roundf((width / (float)_width) * (float)_height);
|
float height = roundf((width / (float)_width) * (float)_height);
|
||||||
|
|
||||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), 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;
|
float lineHeight = size.y;
|
||||||
|
|
||||||
ItemSize(size, style.FramePadding.y);
|
ItemSize(size, style.FramePadding.y);
|
||||||
|
@ -28,6 +28,5 @@ namespace ImGui {
|
|||||||
GLuint textureId;
|
GLuint textureId;
|
||||||
|
|
||||||
bool newData = false;
|
bool newData = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ namespace ImGui {
|
|||||||
float height = roundf((width / (float)_frameWidth) * (float)_lineCount);
|
float height = roundf((width / (float)_frameWidth) * (float)_lineCount);
|
||||||
|
|
||||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), 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;
|
float lineHeight = size.y;
|
||||||
|
|
||||||
// If there are no lines, there is no point in drawing anything
|
// If there are no lines, there is no point in drawing anything
|
||||||
|
@ -37,7 +37,5 @@ namespace ImGui {
|
|||||||
GLuint textureId;
|
GLuint textureId;
|
||||||
|
|
||||||
bool newData = false;
|
bool newData = false;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -4,7 +4,6 @@
|
|||||||
#include <gui/style.h>
|
#include <gui/style.h>
|
||||||
|
|
||||||
Menu::Menu() {
|
Menu::Menu() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::registerEntry(std::string name, void (*drawHandler)(void* ctx), void* ctx, ModuleManager::Instance* inst) {
|
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 posMin = ImGui::GetCursorScreenPos();
|
||||||
ImVec2 posMax = ImVec2(posMin.x + menuWidth, posMin.y + ImGui::GetFrameHeight());
|
ImVec2 posMax = ImVec2(posMin.x + menuWidth, posMin.y + ImGui::GetFrameHeight());
|
||||||
|
|
||||||
headerTops[displayedCount-1] = posMin.y;
|
headerTops[displayedCount - 1] = posMin.y;
|
||||||
optionIDs[displayedCount-1] = rawId-1;
|
optionIDs[displayedCount - 1] = rawId - 1;
|
||||||
|
|
||||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && ImGui::IsMouseHoveringRect(posMin, posMax)) {
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && ImGui::IsMouseHoveringRect(posMin, posMax)) {
|
||||||
menuClicked = true;
|
menuClicked = true;
|
||||||
@ -89,7 +88,7 @@ bool Menu::draw(bool updateStates) {
|
|||||||
|
|
||||||
if (menuClicked && ImGui::IsMouseDragging(ImGuiMouseButton_Left) && draggedMenuName.empty() && clickedMenuName == opt.name) {
|
if (menuClicked && ImGui::IsMouseDragging(ImGuiMouseButton_Left) && draggedMenuName.empty() && clickedMenuName == opt.name) {
|
||||||
draggedMenuName = opt.name;
|
draggedMenuName = opt.name;
|
||||||
draggedId = rawId-1;
|
draggedId = rawId - 1;
|
||||||
draggedOpt = opt;
|
draggedOpt = opt;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <module.h>
|
#include <module.h>
|
||||||
|
|
||||||
#define MAX_MENU_COUNT 1024
|
#define MAX_MENU_COUNT 1024
|
||||||
|
|
||||||
class Menu {
|
class Menu {
|
||||||
public:
|
public:
|
||||||
|
@ -39,7 +39,7 @@ namespace ImGui {
|
|||||||
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), text);
|
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), text);
|
||||||
sprintf(buf, "%d", i * 10);
|
sprintf(buf, "%d", i * 10);
|
||||||
ImVec2 sz = ImGui::CalcTextSize(buf);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,8 +13,8 @@ namespace ImGui {
|
|||||||
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), display_format, *v);
|
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), display_format, *v);
|
||||||
|
|
||||||
// Map from [v_min,v_max] to [0,N]
|
// Map from [v_min,v_max] to [0,N]
|
||||||
const int countValues = int((v_max-v_min)/v_step);
|
const int countValues = int((v_max - v_min) / v_step);
|
||||||
int v_i = int((*v - 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);
|
bool value_changed = ImGui::SliderInt(label, &v_i, 0, countValues, text_buf);
|
||||||
|
|
||||||
// Remap from [0,N] to [v_min,v_max]
|
// Remap from [0,N] to [v_min,v_max]
|
||||||
|
@ -21,7 +21,7 @@ namespace ImGui {
|
|||||||
float pad = style.FramePadding.y;
|
float pad = style.FramePadding.y;
|
||||||
ImVec2 min = window->DC.CursorPos;
|
ImVec2 min = window->DC.CursorPos;
|
||||||
ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), 100);
|
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;
|
float lineHeight = size.y;
|
||||||
|
|
||||||
ItemSize(size, style.FramePadding.y);
|
ItemSize(size, style.FramePadding.y);
|
||||||
@ -29,20 +29,20 @@ namespace ImGui {
|
|||||||
return;
|
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 col = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
|
||||||
ImU32 col2 = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
|
ImU32 col2 = ImGui::GetColorU32(ImGuiCol_CheckMark, 0.7f);
|
||||||
float increment = size.x / (float)sampleCount;
|
float increment = size.x / (float)sampleCount;
|
||||||
float val;
|
float val;
|
||||||
|
|
||||||
for (auto l : lines) {
|
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++) {
|
for (int i = 0; i < sampleCount; i++) {
|
||||||
val = buffer[i] * _scale;
|
val = buffer[i] * _scale;
|
||||||
if (val > 1.0f || val < -1.0f) { continue; }
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,5 @@ namespace ImGui {
|
|||||||
float* buffer;
|
float* buffer;
|
||||||
float _scale;
|
float _scale;
|
||||||
int sampleCount = 0;
|
int sampleCount = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -29,25 +29,25 @@ namespace ImGui {
|
|||||||
|
|
||||||
float zeroDb = roundf(((-val_min) / (val_max - val_min)) * size.x);
|
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, 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 + 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 end = roundf(((avg - val_min) / (val_max - val_min)) * size.x);
|
||||||
float endP = roundf(((peak - val_min) / (val_max - val_min)) * size.x);
|
float endP = roundf(((peak - val_min) / (val_max - val_min)) * size.x);
|
||||||
|
|
||||||
if (avg <= 0) {
|
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 {
|
else {
|
||||||
window->DrawList->AddRectFilled(min, min + ImVec2(zeroDb, lineHeight), IM_COL32( 0, 255, 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 ));
|
window->DrawList->AddRectFilled(min + ImVec2(zeroDb, 0), min + ImVec2(end, lineHeight), IM_COL32(255, 0, 0, 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peak <= 0) {
|
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 {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,32 +10,32 @@
|
|||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
|
|
||||||
float DEFAULT_COLOR_MAP[][3] = {
|
float DEFAULT_COLOR_MAP[][3] = {
|
||||||
{0x00, 0x00, 0x20},
|
{ 0x00, 0x00, 0x20 },
|
||||||
{0x00, 0x00, 0x30},
|
{ 0x00, 0x00, 0x30 },
|
||||||
{0x00, 0x00, 0x50},
|
{ 0x00, 0x00, 0x50 },
|
||||||
{0x00, 0x00, 0x91},
|
{ 0x00, 0x00, 0x91 },
|
||||||
{0x1E, 0x90, 0xFF},
|
{ 0x1E, 0x90, 0xFF },
|
||||||
{0xFF, 0xFF, 0xFF},
|
{ 0xFF, 0xFF, 0xFF },
|
||||||
{0xFF, 0xFF, 0x00},
|
{ 0xFF, 0xFF, 0x00 },
|
||||||
{0xFE, 0x6D, 0x16},
|
{ 0xFE, 0x6D, 0x16 },
|
||||||
{0xFF, 0x00, 0x00},
|
{ 0xFF, 0x00, 0x00 },
|
||||||
{0xC6, 0x00, 0x00},
|
{ 0xC6, 0x00, 0x00 },
|
||||||
{0x9F, 0x00, 0x00},
|
{ 0x9F, 0x00, 0x00 },
|
||||||
{0x75, 0x00, 0x00},
|
{ 0x75, 0x00, 0x00 },
|
||||||
{0x4A, 0x00, 0x00}
|
{ 0x4A, 0x00, 0x00 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Fix this hacky BS
|
// TODO: Fix this hacky BS
|
||||||
|
|
||||||
double freq_ranges[] = {
|
double freq_ranges[] = {
|
||||||
1.0, 2.0, 2.5, 5.0,
|
1.0, 2.0, 2.5, 5.0,
|
||||||
10.0, 20.0, 25.0, 50.0,
|
10.0, 20.0, 25.0, 50.0,
|
||||||
100.0, 200.0, 250.0, 500.0,
|
100.0, 200.0, 250.0, 500.0,
|
||||||
1000.0, 2000.0, 2500.0, 5000.0,
|
1000.0, 2000.0, 2500.0, 5000.0,
|
||||||
10000.0, 20000.0, 25000.0, 50000.0,
|
10000.0, 20000.0, 25000.0, 50000.0,
|
||||||
100000.0, 200000.0, 250000.0, 500000.0,
|
100000.0, 200000.0, 250000.0, 500000.0,
|
||||||
1000000.0, 2000000.0, 2500000.0, 5000000.0,
|
1000000.0, 2000000.0, 2500000.0, 5000000.0,
|
||||||
10000000.0, 20000000.0, 25000000.0, 50000000.0
|
10000000.0, 20000000.0, 25000000.0, 50000000.0
|
||||||
};
|
};
|
||||||
|
|
||||||
inline double findBestRange(double bandwidth, int maxSteps) {
|
inline double findBestRange(double bandwidth, int maxSteps) {
|
||||||
@ -105,8 +105,8 @@ namespace ImGui {
|
|||||||
for (float line = startLine; line > fftMin; line -= vRange) {
|
for (float line = startLine; line > fftMin; line -= vRange) {
|
||||||
float yPos = widgetPos.y + fftHeight + 10 - ((line - fftMin) * scaleFactor);
|
float yPos = widgetPos.y + fftHeight + 10 - ((line - fftMin) * scaleFactor);
|
||||||
window->DrawList->AddLine(ImVec2(roundf(widgetPos.x + 50), roundf(yPos)),
|
window->DrawList->AddLine(ImVec2(roundf(widgetPos.x + 50), roundf(yPos)),
|
||||||
ImVec2(roundf(widgetPos.x + dataWidth + 50), roundf(yPos)),
|
ImVec2(roundf(widgetPos.x + dataWidth + 50), roundf(yPos)),
|
||||||
IM_COL32(50, 50, 50, 255), 1.0);
|
IM_COL32(50, 50, 50, 255), 1.0);
|
||||||
sprintf(buf, "%d", (int)line);
|
sprintf(buf, "%d", (int)line);
|
||||||
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||||
window->DrawList->AddText(ImVec2(widgetPos.x + 40 - txtSz.x, roundf(yPos - (txtSz.y / 2.0))), text, 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) {
|
for (double freq = startFreq; freq < upperFreq; freq += range) {
|
||||||
double xPos = widgetPos.x + 50 + ((freq - lowerFreq) * horizScale);
|
double xPos = widgetPos.x + 50 + ((freq - lowerFreq) * horizScale);
|
||||||
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + 10),
|
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + 10),
|
||||||
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
||||||
IM_COL32(50, 50, 50, 255), 1.0);
|
IM_COL32(50, 50, 50, 255), 1.0);
|
||||||
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
||||||
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
|
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
|
||||||
text, 1.0);
|
text, 1.0);
|
||||||
printAndScale(freq, buf);
|
printAndScale(freq, buf);
|
||||||
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||||
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), widgetPos.y + fftHeight + 10 + txtSz.y), text, 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
|
// Data
|
||||||
if (latestFFT != NULL && fftLines != 0) {
|
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 aPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i - 1] - fftMin) * scaleFactor);
|
||||||
double bPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i] - fftMin) * scaleFactor);
|
double bPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i] - fftMin) * scaleFactor);
|
||||||
aPos = std::clamp<double>(aPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
|
aPos = std::clamp<double>(aPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
|
||||||
bPos = std::clamp<double>(bPos, 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)),
|
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)),
|
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
|
// X Axis
|
||||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10),
|
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10),
|
||||||
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
|
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
|
||||||
text, 1.0);
|
text, 1.0);
|
||||||
// Y Axis
|
// Y Axis
|
||||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9),
|
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9),
|
||||||
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
|
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
|
||||||
text, 1.0);
|
text, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterFall::drawWaterfall() {
|
void WaterFall::drawWaterfall() {
|
||||||
@ -211,7 +211,7 @@ namespace ImGui {
|
|||||||
|
|
||||||
bool mouseHovered, mouseHeld;
|
bool mouseHovered, mouseHeld;
|
||||||
bool mouseClicked = ImGui::ButtonBehavior(ImRect(fftAreaMin, wfMax), GetID("WaterfallID"), &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);
|
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);
|
mouseInFreq = IS_IN_AREA(dragOrigin, freqAreaMin, freqAreaMax);
|
||||||
@ -268,11 +268,15 @@ namespace ImGui {
|
|||||||
bool resizing = false;
|
bool resizing = false;
|
||||||
if (_vfo->reference != REF_LOWER) {
|
if (_vfo->reference != REF_LOWER) {
|
||||||
if (IS_IN_AREA(mousePos, _vfo->lbwSelMin, _vfo->lbwSelMax)) { resizing = true; }
|
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 (_vfo->reference != REF_UPPER) {
|
||||||
if (IS_IN_AREA(mousePos, _vfo->rbwSelMin, _vfo->rbwSelMax)) { resizing = true; }
|
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; }
|
if (!resizing) { continue; }
|
||||||
relatedVfo = _vfo;
|
relatedVfo = _vfo;
|
||||||
@ -386,7 +390,7 @@ namespace ImGui {
|
|||||||
// If the left and right keys are pressed while hovering the freq scale, move it too
|
// If the left and right keys are pressed while hovering the freq scale, move it too
|
||||||
bool leftKeyPressed = ImGui::IsKeyPressed(GLFW_KEY_LEFT);
|
bool leftKeyPressed = ImGui::IsKeyPressed(GLFW_KEY_LEFT);
|
||||||
if ((leftKeyPressed || ImGui::IsKeyPressed(GLFW_KEY_RIGHT)) && mouseInFreq) {
|
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) {
|
if (viewOffset + (viewBandwidth / 2.0) > wholeBandwidth / 2.0) {
|
||||||
double freqOffset = (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
|
// 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) {
|
if (selVfo != NULL) {
|
||||||
int refCenter = mousePos.x - (widgetPos.x + 50);
|
int refCenter = mousePos.x - (widgetPos.x + 50);
|
||||||
if (refCenter >= 0 && refCenter < dataWidth) {
|
if (refCenter >= 0 && refCenter < dataWidth) {
|
||||||
@ -509,13 +513,13 @@ namespace ImGui {
|
|||||||
|
|
||||||
// Calculate FFT index data
|
// Calculate FFT index data
|
||||||
double vfoMinSizeFreq = _vfo->centerOffset - _vfo->bandwidth;
|
double vfoMinSizeFreq = _vfo->centerOffset - _vfo->bandwidth;
|
||||||
double vfoMinFreq = _vfo->centerOffset - (_vfo->bandwidth/2.0);
|
double vfoMinFreq = _vfo->centerOffset - (_vfo->bandwidth / 2.0);
|
||||||
double vfoMaxFreq = _vfo->centerOffset + (_vfo->bandwidth/2.0);
|
double vfoMaxFreq = _vfo->centerOffset + (_vfo->bandwidth / 2.0);
|
||||||
double vfoMaxSizeFreq = _vfo->centerOffset + _vfo->bandwidth;
|
double vfoMaxSizeFreq = _vfo->centerOffset + _vfo->bandwidth;
|
||||||
int vfoMinSideOffset = std::clamp<int>(((vfoMinSizeFreq / (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 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 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 vfoMaxSideOffset = std::clamp<int>(((vfoMaxSizeFreq / (wholeBandwidth / 2.0)) * (double)(rawFFTSize / 2)) + (rawFFTSize / 2), 0, rawFFTSize);
|
||||||
|
|
||||||
double avg = 0;
|
double avg = 0;
|
||||||
float max = -INFINITY;
|
float max = -INFINITY;
|
||||||
@ -638,19 +642,19 @@ namespace ImGui {
|
|||||||
}
|
}
|
||||||
if (width >= 1.0) {
|
if (width >= 1.0) {
|
||||||
window->DrawList->AddRectFilled(ImVec2(roundf(aPos), bpBottom - height),
|
window->DrawList->AddRectFilled(ImVec2(roundf(aPos), bpBottom - height),
|
||||||
ImVec2(roundf(bPos), bpBottom), colorTrans);
|
ImVec2(roundf(bPos), bpBottom), colorTrans);
|
||||||
if (startVis) {
|
if (startVis) {
|
||||||
window->DrawList->AddLine(ImVec2(roundf(aPos), bpBottom - height - 1),
|
window->DrawList->AddLine(ImVec2(roundf(aPos), bpBottom - height - 1),
|
||||||
ImVec2(roundf(aPos), bpBottom - 1), color);
|
ImVec2(roundf(aPos), bpBottom - 1), color);
|
||||||
}
|
}
|
||||||
if (endVis) {
|
if (endVis) {
|
||||||
window->DrawList->AddLine(ImVec2(roundf(bPos), bpBottom - height - 1),
|
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) {
|
if (txtSz.x <= width) {
|
||||||
window->DrawList->AddText(ImVec2(cPos - (txtSz.x / 2.0), bpBottom - (height / 2.0f) - (txtSz.y / 2.0f)),
|
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;
|
waterfallHeight = widgetSize.y - fftHeight - 52;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fftHeight = widgetSize.y - 50;
|
fftHeight = widgetSize.y - 50;
|
||||||
}
|
}
|
||||||
dataWidth = widgetSize.x - 60.0;
|
dataWidth = widgetSize.x - 60.0;
|
||||||
|
|
||||||
@ -766,7 +770,7 @@ namespace ImGui {
|
|||||||
//window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
|
//window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
|
||||||
ImU32 bg = ImGui::ColorConvertFloat4ToU32(gui::themeManager.waterfallBg);
|
ImU32 bg = ImGui::ColorConvertFloat4ToU32(gui::themeManager.waterfallBg);
|
||||||
window->DrawList->AddRectFilled(widgetPos, widgetEndPos, bg);
|
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);
|
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) {
|
if (!gui::mainWindow.lockWaterfallControls) {
|
||||||
@ -1138,7 +1142,6 @@ namespace ImGui {
|
|||||||
}
|
}
|
||||||
reference = ref;
|
reference = ref;
|
||||||
setOffset(generalOffset);
|
setOffset(generalOffset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallVFO::updateDrawingVars(double viewBandwidth, float dataWidth, double viewOffset, ImVec2 widgetPos, int fftHeight) {
|
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 (rectMax.x - rectMin.x < 10) { return; }
|
||||||
if (reference != REF_LOWER && !bandwidthLocked && !leftClamped) {
|
if (reference != REF_LOWER && !bandwidthLocked && !leftClamped) {
|
||||||
if (IS_IN_AREA(mousePos, lbwSelMin, lbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
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 (reference != REF_UPPER && !bandwidthLocked && !rightClamped) {
|
||||||
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
|
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() {
|
void WaterFall::showWaterfall() {
|
||||||
buf_mtx.lock();
|
buf_mtx.lock();
|
||||||
if (rawFFTs == NULL) {
|
if (rawFFTs == NULL) {
|
||||||
spdlog::error("Null rawFFT");
|
spdlog::error("Null rawFFT");
|
||||||
}
|
}
|
||||||
waterfallVisible = true;
|
waterfallVisible = true;
|
||||||
@ -1254,4 +1261,3 @@ namespace ImGui {
|
|||||||
snapInterval = interval;
|
snapInterval = interval;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <utils/event.h>
|
#include <utils/event.h>
|
||||||
|
|
||||||
#define WATERFALL_RESOLUTION 1000000
|
#define WATERFALL_RESOLUTION 1000000
|
||||||
|
|
||||||
namespace ImGui {
|
namespace ImGui {
|
||||||
class WaterfallVFO {
|
class WaterfallVFO {
|
||||||
@ -270,9 +270,9 @@ namespace ImGui {
|
|||||||
int maxVSteps;
|
int maxVSteps;
|
||||||
int maxHSteps;
|
int maxHSteps;
|
||||||
|
|
||||||
int dataWidth; // Width of the FFT and waterfall
|
int dataWidth; // Width of the FFT and waterfall
|
||||||
int fftHeight; // Height of the fft graph
|
int fftHeight; // Height of the fft graph
|
||||||
int waterfallHeight = 0; // Height of the waterfall
|
int waterfallHeight = 0; // Height of the waterfall
|
||||||
|
|
||||||
double viewBandwidth;
|
double viewBandwidth;
|
||||||
double viewOffset;
|
double viewOffset;
|
||||||
|
@ -22,10 +22,10 @@ ModuleManager::Module_t ModuleManager::loadModule(std::string path) {
|
|||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
mod.info = (ModuleInfo_t*)GetProcAddress(mod.handle, "_INFO_");
|
mod.info = (ModuleInfo_t*)GetProcAddress(mod.handle, "_INFO_");
|
||||||
mod.init = (void(*)())GetProcAddress(mod.handle, "_INIT_");
|
mod.init = (void (*)())GetProcAddress(mod.handle, "_INIT_");
|
||||||
mod.createInstance = (Instance*(*)(std::string))GetProcAddress(mod.handle, "_CREATE_INSTANCE_");
|
mod.createInstance = (Instance * (*)(std::string)) GetProcAddress(mod.handle, "_CREATE_INSTANCE_");
|
||||||
mod.deleteInstance = (void(*)(Instance*))GetProcAddress(mod.handle, "_DELETE_INSTANCE_");
|
mod.deleteInstance = (void (*)(Instance*))GetProcAddress(mod.handle, "_DELETE_INSTANCE_");
|
||||||
mod.end = (void(*)())GetProcAddress(mod.handle, "_END_");
|
mod.end = (void (*)())GetProcAddress(mod.handle, "_END_");
|
||||||
#else
|
#else
|
||||||
mod.handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
mod.handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||||
if (mod.handle == NULL) {
|
if (mod.handle == NULL) {
|
||||||
@ -34,10 +34,10 @@ ModuleManager::Module_t ModuleManager::loadModule(std::string path) {
|
|||||||
return mod;
|
return mod;
|
||||||
}
|
}
|
||||||
mod.info = (ModuleInfo_t*)dlsym(mod.handle, "_INFO_");
|
mod.info = (ModuleInfo_t*)dlsym(mod.handle, "_INFO_");
|
||||||
mod.init = (void(*)())dlsym(mod.handle, "_INIT_");
|
mod.init = (void (*)())dlsym(mod.handle, "_INIT_");
|
||||||
mod.createInstance = (Instance*(*)(std::string))dlsym(mod.handle, "_CREATE_INSTANCE_");
|
mod.createInstance = (Instance * (*)(std::string)) dlsym(mod.handle, "_CREATE_INSTANCE_");
|
||||||
mod.deleteInstance = (void(*)(Instance*))dlsym(mod.handle, "_DELETE_INSTANCE_");
|
mod.deleteInstance = (void (*)(Instance*))dlsym(mod.handle, "_DELETE_INSTANCE_");
|
||||||
mod.end = (void(*)())dlsym(mod.handle, "_END_");
|
mod.end = (void (*)())dlsym(mod.handle, "_END_");
|
||||||
#endif
|
#endif
|
||||||
if (mod.info == NULL) {
|
if (mod.info == NULL) {
|
||||||
spdlog::error("{0} is missing _INFO_ symbol", path);
|
spdlog::error("{0} is missing _INFO_ symbol", path);
|
||||||
@ -107,7 +107,7 @@ int ModuleManager::deleteInstance(std::string name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
onInstanceDelete.emit(name);
|
onInstanceDelete.emit(name);
|
||||||
Instance_t inst = instances[name];
|
Instance_t inst = instances[name];
|
||||||
inst.module.deleteInstance(inst.instance);
|
inst.module.deleteInstance(inst.instance);
|
||||||
instances.erase(name);
|
instances.erase(name);
|
||||||
onInstanceDeleted.emit(name);
|
onInstanceDeleted.emit(name);
|
||||||
|
@ -15,17 +15,17 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#define MOD_EXPORT extern "C" __declspec(dllexport)
|
#define MOD_EXPORT extern "C" __declspec(dllexport)
|
||||||
#define SDRPP_MOD_EXTENTSION ".dll"
|
#define SDRPP_MOD_EXTENTSION ".dll"
|
||||||
#else
|
#else
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#define MOD_EXPORT extern "C"
|
#define MOD_EXPORT extern "C"
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define SDRPP_MOD_EXTENTSION ".dylib"
|
#define SDRPP_MOD_EXTENTSION ".dylib"
|
||||||
#else
|
#else
|
||||||
#define SDRPP_MOD_EXTENTSION ".so"
|
#define SDRPP_MOD_EXTENTSION ".so"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class ModuleManager {
|
class ModuleManager {
|
||||||
@ -98,7 +98,6 @@ public:
|
|||||||
|
|
||||||
std::map<std::string, ModuleManager::Module_t> modules;
|
std::map<std::string, ModuleManager::Module_t> modules;
|
||||||
std::map<std::string, ModuleManager::Instance_t> instances;
|
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_
|
@ -18,7 +18,7 @@ namespace options {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse(int argc, char *argv[]) {
|
bool parse(int argc, char* argv[]) {
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
char* arg = argv[i];
|
char* arg = argv[i];
|
||||||
if (!strcmp(arg, "-r") || !strcmp(arg, "--root")) {
|
if (!strcmp(arg, "-r") || !strcmp(arg, "--root")) {
|
||||||
|
@ -12,5 +12,5 @@ namespace options {
|
|||||||
SDRPP_EXPORT CMDLineOptions opts;
|
SDRPP_EXPORT CMDLineOptions opts;
|
||||||
|
|
||||||
void loadDefaults();
|
void loadDefaults();
|
||||||
bool parse(int argc, char *argv[]);
|
bool parse(int argc, char* argv[]);
|
||||||
}
|
}
|
@ -2,10 +2,9 @@
|
|||||||
#include <core.h>
|
#include <core.h>
|
||||||
|
|
||||||
SignalPath::SignalPath() {
|
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->sampleRate = sampleRate;
|
||||||
this->sourceSampleRate = sampleRate;
|
this->sourceSampleRate = sampleRate;
|
||||||
this->fftRate = fftRate;
|
this->fftRate = fftRate;
|
||||||
@ -195,13 +194,13 @@ void SignalPath::setDecimation(int dec) {
|
|||||||
decimator = new dsp::HalfDecimator<dsp::complex_t>(&inputBuffer.out, &halfBandWindow);
|
decimator = new dsp::HalfDecimator<dsp::complex_t>(&inputBuffer.out, &halfBandWindow);
|
||||||
}
|
}
|
||||||
else {
|
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(); }
|
if (running) { decimator->start(); }
|
||||||
decimators.push_back(decimator);
|
decimators.push_back(decimator);
|
||||||
}
|
}
|
||||||
split.setInput(&decimators[decimators.size()-1]->out);
|
split.setInput(&decimators[decimators.size() - 1]->out);
|
||||||
if (running) { split.start(); }
|
if (running) { split.start(); }
|
||||||
|
|
||||||
// Update the DSP sample rate
|
// Update the DSP sample rate
|
||||||
@ -247,12 +246,12 @@ void SignalPath::setFFTWindow(int win) {
|
|||||||
void SignalPath::generateFFTWindow(int win, float* taps, int size) {
|
void SignalPath::generateFFTWindow(int win, float* taps, int size) {
|
||||||
if (win == FFT_WINDOW_RECTANGULAR) {
|
if (win == FFT_WINDOW_RECTANGULAR) {
|
||||||
for (int i = 0; i < size; i++) {
|
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) {
|
else if (win == FFT_WINDOW_BLACKMAN) {
|
||||||
for (int i = 0; i < size; i++) {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ enum {
|
|||||||
class SignalPath {
|
class SignalPath {
|
||||||
public:
|
public:
|
||||||
SignalPath();
|
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 start();
|
||||||
void stop();
|
void stop();
|
||||||
void setSampleRate(double sampleRate);
|
void setSampleRate(double sampleRate);
|
||||||
|
@ -86,7 +86,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
dsp::NullSink<dsp::stereo_t> ns;
|
dsp::NullSink<dsp::stereo_t> ns;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void registerSinkProvider(std::string name, SinkProvider provider);
|
void registerSinkProvider(std::string name, SinkProvider provider);
|
||||||
@ -130,5 +129,4 @@ private:
|
|||||||
std::vector<std::string> providerNames;
|
std::vector<std::string> providerNames;
|
||||||
std::string providerNamesTxt;
|
std::string providerNamesTxt;
|
||||||
std::vector<std::string> streamNames;
|
std::vector<std::string> streamNames;
|
||||||
|
|
||||||
};
|
};
|
@ -3,7 +3,6 @@
|
|||||||
#include <signal_path/signal_path.h>
|
#include <signal_path/signal_path.h>
|
||||||
|
|
||||||
SourceManager::SourceManager() {
|
SourceManager::SourceManager() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceManager::registerSource(std::string name, SourceHandler* handler) {
|
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> SourceManager::getSourceNames() {
|
||||||
std::vector<std::string> names;
|
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;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceManager::selectSource(std::string name) {
|
void SourceManager::selectSource(std::string name) {
|
||||||
if (sources.find(name) == sources.end()) {
|
if (sources.find(name) == sources.end()) {
|
||||||
spdlog::error("Tried to select non existent source: {0}", name);
|
spdlog::error("Tried to select non existent source: {0}", name);
|
||||||
return;
|
return;
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
void registerSource(std::string name, SourceHandler* handler);
|
void registerSource(std::string name, SourceHandler* handler);
|
||||||
void unregisterSource(std::string name);
|
void unregisterSource(std::string name);
|
||||||
void selectSource(std::string name);
|
void selectSource(std::string name);
|
||||||
void showSelectedMenu();
|
void showSelectedMenu();
|
||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
@ -43,5 +43,4 @@ private:
|
|||||||
double tuneOffset;
|
double tuneOffset;
|
||||||
double currentFreq;
|
double currentFreq;
|
||||||
dsp::stream<dsp::complex_t> nullSource;
|
dsp::stream<dsp::complex_t> nullSource;
|
||||||
|
|
||||||
};
|
};
|
@ -87,7 +87,6 @@ std::string VFOManager::VFO::getName() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VFOManager::VFOManager() {
|
VFOManager::VFOManager() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VFOManager::VFO* VFOManager::createVFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked) {
|
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();
|
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()) {
|
if (vfos.find(name) == vfos.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VFOManager::VFO* createVFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked);
|
VFOManager::VFO* createVFO(std::string name, int reference, double offset, double bandwidth, double sampleRate, double minBandwidth, double maxBandwidth, bool bandwidthLocked);
|
||||||
|
@ -11,9 +11,15 @@ namespace color {
|
|||||||
|
|
||||||
// Calculate the hue
|
// Calculate the hue
|
||||||
if (delta == 0) { h = 0; }
|
if (delta == 0) { h = 0; }
|
||||||
else if (r > g && r > b) { h = 60.0f * fmodf((g - b) / delta, 6.0f); }
|
else if (r > g && r > b) {
|
||||||
else if (g > r && g > b) { h = 60.0f * (((b - r) / delta) + 2.0f); }
|
h = 60.0f * fmodf((g - b) / delta, 6.0f);
|
||||||
else { h = 60.0f * (((r - g) / delta) + 4.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
|
// Calculate lightness
|
||||||
l = (cmin + cmax) / 2.0f;
|
l = (cmin + cmax) / 2.0f;
|
||||||
@ -29,12 +35,36 @@ namespace color {
|
|||||||
float m = l - (c / 2.0f);
|
float m = l - (c / 2.0f);
|
||||||
|
|
||||||
// Affect coefficients to R, G or B depending on hue
|
// Affect coefficients to R, G or B depending on hue
|
||||||
if (h < 60) { r = c; g = x; b = 0; }
|
if (h < 60) {
|
||||||
else if (h < 120) { r = x; g = c; b = 0; }
|
r = c;
|
||||||
else if (h < 180) { r = 0; g = c; b = x; }
|
g = x;
|
||||||
else if (h < 240) { r = 0; g = x; b = c; }
|
b = 0;
|
||||||
else if (h < 300) { r = x; g = 0; b = c; }
|
}
|
||||||
else { r = c; g = 0; b = x; }
|
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
|
// Add m
|
||||||
r += m;
|
r += m;
|
||||||
|
@ -40,5 +40,4 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<EventHandler<T>*> handlers;
|
std::vector<EventHandler<T>*> handlers;
|
||||||
|
|
||||||
};
|
};
|
@ -9,7 +9,10 @@ namespace utils {
|
|||||||
int len = strlen(str) - 1;
|
int len = strlen(str) - 1;
|
||||||
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
||||||
len--;
|
len--;
|
||||||
if (str[len] == '.') { len--; break; }
|
if (str[len] == '.') {
|
||||||
|
len--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return std::string(str).substr(0, len + 1) + "MHz";
|
return std::string(str).substr(0, len + 1) + "MHz";
|
||||||
}
|
}
|
||||||
@ -18,7 +21,10 @@ namespace utils {
|
|||||||
int len = strlen(str) - 1;
|
int len = strlen(str) - 1;
|
||||||
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
||||||
len--;
|
len--;
|
||||||
if (str[len] == '.') { len--; break; }
|
if (str[len] == '.') {
|
||||||
|
len--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return std::string(str).substr(0, len + 1) + "KHz";
|
return std::string(str).substr(0, len + 1) + "KHz";
|
||||||
}
|
}
|
||||||
@ -27,7 +33,10 @@ namespace utils {
|
|||||||
int len = strlen(str) - 1;
|
int len = strlen(str) - 1;
|
||||||
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
while ((str[len] == '0' || str[len] == '.') && len > 0) {
|
||||||
len--;
|
len--;
|
||||||
if (str[len] == '.') { len--; break; }
|
if (str[len] == '.') {
|
||||||
|
len--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return std::string(str).substr(0, len + 1) + "Hz";
|
return std::string(str).substr(0, len + 1) + "Hz";
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ namespace net {
|
|||||||
|
|
||||||
void ConnClass::waitForEnd() {
|
void ConnClass::waitForEnd() {
|
||||||
std::unique_lock lck(readQueueMtx);
|
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) {
|
int ConnClass::read(int count, uint8_t* buf) {
|
||||||
@ -148,7 +148,7 @@ namespace net {
|
|||||||
while (true) {
|
while (true) {
|
||||||
// Wait for wakeup and exit if it's for terminating the thread
|
// Wait for wakeup and exit if it's for terminating the thread
|
||||||
std::unique_lock lck(readQueueMtx);
|
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; }
|
if (stopWorkers || !connectionOpen) { return; }
|
||||||
|
|
||||||
// Pop first element off the list
|
// Pop first element off the list
|
||||||
@ -174,7 +174,7 @@ namespace net {
|
|||||||
while (true) {
|
while (true) {
|
||||||
// Wait for wakeup and exit if it's for terminating the thread
|
// Wait for wakeup and exit if it's for terminating the thread
|
||||||
std::unique_lock lck(writeQueueMtx);
|
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; }
|
if (stopWorkers || !connectionOpen) { return; }
|
||||||
|
|
||||||
// Pop first element off the list
|
// Pop first element off the list
|
||||||
@ -261,7 +261,6 @@ namespace net {
|
|||||||
if (acceptWorkerThread.joinable()) { acceptWorkerThread.join(); }
|
if (acceptWorkerThread.joinable()) { acceptWorkerThread.join(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
listening = false;
|
listening = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +272,7 @@ namespace net {
|
|||||||
while (true) {
|
while (true) {
|
||||||
// Wait for wakeup and exit if it's for terminating the thread
|
// Wait for wakeup and exit if it's for terminating the thread
|
||||||
std::unique_lock lck(acceptQueueMtx);
|
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; }
|
if (stopWorker || !listening) { return; }
|
||||||
|
|
||||||
// Pop first element off the list
|
// Pop first element off the list
|
||||||
@ -299,13 +298,13 @@ namespace net {
|
|||||||
|
|
||||||
|
|
||||||
Conn connect(std::string host, uint16_t port) {
|
Conn connect(std::string host, uint16_t port) {
|
||||||
Socket sock;
|
Socket sock;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Initialize WinSock2
|
// Initialize WinSock2
|
||||||
if (!winsock_init) {
|
if (!winsock_init) {
|
||||||
WSADATA wsa;
|
WSADATA wsa;
|
||||||
if (WSAStartup(MAKEWORD(2,2),&wsa)) {
|
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
|
||||||
throw std::runtime_error("Could not initialize WinSock2");
|
throw std::runtime_error("Could not initialize WinSock2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -335,7 +334,7 @@ namespace net {
|
|||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
addr.sin_addr.s_addr = *naddr;
|
addr.sin_addr.s_addr = *naddr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
// Connect to host
|
// Connect to host
|
||||||
if (::connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
if (::connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
@ -353,7 +352,7 @@ namespace net {
|
|||||||
// Initialize WinSock2
|
// Initialize WinSock2
|
||||||
if (!winsock_init) {
|
if (!winsock_init) {
|
||||||
WSADATA wsa;
|
WSADATA wsa;
|
||||||
if (WSAStartup(MAKEWORD(2,2),&wsa)) {
|
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
|
||||||
throw std::runtime_error("Could not initialize WinSock2");
|
throw std::runtime_error("Could not initialize WinSock2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -377,7 +376,7 @@ namespace net {
|
|||||||
// This option has a different meaning on Windows,
|
// This option has a different meaning on Windows,
|
||||||
// so we use it only for non-Windows systems
|
// so we use it only for non-Windows systems
|
||||||
int enable = 1;
|
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");
|
throw std::runtime_error("Could not configure socket");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -395,7 +394,7 @@ namespace net {
|
|||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
addr.sin_addr.s_addr = *naddr;
|
addr.sin_addr.s_addr = *naddr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
// Bind socket
|
// Bind socket
|
||||||
if (bind(listenSock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
if (bind(listenSock, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
@ -419,7 +418,7 @@ namespace net {
|
|||||||
// Initialize WinSock2
|
// Initialize WinSock2
|
||||||
if (!winsock_init) {
|
if (!winsock_init) {
|
||||||
WSADATA wsa;
|
WSADATA wsa;
|
||||||
if (WSAStartup(MAKEWORD(2,2),&wsa)) {
|
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
|
||||||
throw std::runtime_error("Could not initialize WinSock2");
|
throw std::runtime_error("Could not initialize WinSock2");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -455,15 +454,15 @@ namespace net {
|
|||||||
|
|
||||||
// Create host address
|
// Create host address
|
||||||
struct sockaddr_in addr;
|
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_family = AF_INET;
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
// Create remote host address
|
// Create remote host address
|
||||||
struct sockaddr_in raddr;
|
struct sockaddr_in raddr;
|
||||||
raddr.sin_addr.s_addr = *rnaddr;
|
raddr.sin_addr.s_addr = *rnaddr;
|
||||||
raddr.sin_family = AF_INET;
|
raddr.sin_family = AF_INET;
|
||||||
raddr.sin_port = htons(remotePort);
|
raddr.sin_port = htons(remotePort);
|
||||||
|
|
||||||
// Bind socket
|
// Bind socket
|
||||||
if (bindSocket) {
|
if (bindSocket) {
|
||||||
|
@ -78,7 +78,6 @@ namespace net {
|
|||||||
Socket _sock;
|
Socket _sock;
|
||||||
bool _udp;
|
bool _udp;
|
||||||
struct sockaddr_in remoteAddr;
|
struct sockaddr_in remoteAddr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<ConnClass> Conn;
|
typedef std::unique_ptr<ConnClass> Conn;
|
||||||
@ -112,7 +111,6 @@ namespace net {
|
|||||||
std::thread acceptWorkerThread;
|
std::thread acceptWorkerThread;
|
||||||
|
|
||||||
Socket sock;
|
Socket sock;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<ListenerClass> Listener;
|
typedef std::unique_ptr<ListenerClass> Listener;
|
||||||
|
@ -95,7 +95,7 @@ public:
|
|||||||
return values[id];
|
return values[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
T operator [](int& id) {
|
T operator[](int& id) {
|
||||||
return value(id);
|
return value(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,5 +115,4 @@ private:
|
|||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
std::vector<T> values;
|
std::vector<T> values;
|
||||||
std::string _txt;
|
std::string _txt;
|
||||||
|
|
||||||
};
|
};
|
@ -3,37 +3,36 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
// WTF???
|
// WTF???
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#include <correct.h>
|
#include <correct.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t toDB[] = {
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
0x3e, 0x45, 0xf2, 0x89, 0x5d, 0x26, 0x6b, 0x10, 0xc4, 0xbf
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t fromDB[] = {
|
const uint8_t fromDB[] = {
|
||||||
0x00, 0xcc, 0xac, 0x60, 0x79, 0xb5, 0xd5, 0x19, 0xf0, 0x3c, 0x5c, 0x90, 0x89, 0x45, 0x25, 0xe9, 0xfd, 0x31, 0x51, 0x9d,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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,
|
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
|
0xe1, 0x81, 0x4d, 0xa4, 0x68, 0x08, 0xc4, 0xdd, 0x11, 0x71, 0xbd
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t randVals[] = {
|
const uint8_t randVals[] = {
|
||||||
@ -85,29 +84,44 @@ namespace dsp {
|
|||||||
uint8_t* data = _in->readBuf + 4;
|
uint8_t* data = _in->readBuf + 4;
|
||||||
|
|
||||||
// Deinterleave
|
// Deinterleave
|
||||||
for (int i = 0; i < 255*5; i++) {
|
for (int i = 0; i < 255 * 5; i++) {
|
||||||
buffers[i%5][i/5] = fromDB[data[i]];
|
buffers[i % 5][i / 5] = fromDB[data[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reed the solomon :weary:
|
// Reed the solomon :weary:
|
||||||
int result = 0;
|
int result = 0;
|
||||||
result = correct_reed_solomon_decode(rs, buffers[0], 255, outBuffers[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]);
|
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]);
|
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]);
|
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]);
|
result = correct_reed_solomon_decode(rs, buffers[4], 255, outBuffers[4]);
|
||||||
if (result == -1) { _in->flush(); return count; }
|
if (result == -1) {
|
||||||
|
_in->flush();
|
||||||
// Reinterleave
|
return count;
|
||||||
for (int i = 0; i < 255*5; i++) {
|
|
||||||
out.writeBuf[i] = toDB[outBuffers[i%5][i/5]] ^ randVals[i % 255];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
_in->flush();
|
||||||
return count;
|
return count;
|
||||||
@ -122,6 +136,5 @@ namespace dsp {
|
|||||||
correct_reed_solomon* rs;
|
correct_reed_solomon* rs;
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -85,8 +85,7 @@ namespace dsp {
|
|||||||
break;
|
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 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)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 the packet doesn't fit the frame, save and go to next frame
|
||||||
if (dataLen - i < length) {
|
if (dataLen - i < length) {
|
||||||
@ -99,7 +98,6 @@ namespace dsp {
|
|||||||
memcpy(out.writeBuf, &data[i], length);
|
memcpy(out.writeBuf, &data[i], length);
|
||||||
out.swap(length);
|
out.swap(length);
|
||||||
i += length;
|
i += length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_in->flush();
|
_in->flush();
|
||||||
@ -116,6 +114,5 @@ namespace dsp {
|
|||||||
uint8_t packet[0x4008];
|
uint8_t packet[0x4008];
|
||||||
|
|
||||||
stream<uint8_t>* _in;
|
stream<uint8_t>* _in;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -23,9 +23,9 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#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",
|
/* Name: */ "falcon9_decoder",
|
||||||
/* Description: */ "Falcon9 telemetry decoder for SDR++",
|
/* Description: */ "Falcon9 telemetry decoder for SDR++",
|
||||||
/* Author: */ "Ryzerth",
|
/* Author: */ "Ryzerth",
|
||||||
@ -33,7 +33,7 @@ SDRPP_MOD_INFO {
|
|||||||
/* Max instances */ -1
|
/* Max instances */ -1
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INPUT_SAMPLE_RATE 6000000
|
#define INPUT_SAMPLE_RATE 6000000
|
||||||
|
|
||||||
std::ofstream file("output.ts");
|
std::ofstream file("output.ts");
|
||||||
|
|
||||||
@ -84,7 +84,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~Falcon9DecoderModule() {
|
~Falcon9DecoderModule() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() {}
|
||||||
@ -187,8 +186,7 @@ private:
|
|||||||
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
|
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
|
||||||
|
|
||||||
uint16_t length = (((data[0] & 0b1111) << 8) | data[1]) + 2;
|
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 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)data[6] << 24) | ((uint64_t)data[7] << 16) | ((uint64_t)data[8] << 8) | data[9];
|
|
||||||
|
|
||||||
if (pktId == 0x0117FE0800320303 || pktId == 0x0112FA0800320303) {
|
if (pktId == 0x0117FE0800320303 || pktId == 0x0112FA0800320303) {
|
||||||
data[length - 2] = 0;
|
data[length - 2] = 0;
|
||||||
@ -207,7 +205,7 @@ private:
|
|||||||
static void symSinkHandler(float* data, int count, void* ctx) {
|
static void symSinkHandler(float* data, int count, void* ctx) {
|
||||||
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
|
Falcon9DecoderModule* _this = (Falcon9DecoderModule*)ctx;
|
||||||
float* buf = _this->symDiag.acquireBuffer();
|
float* buf = _this->symDiag.acquireBuffer();
|
||||||
memcpy(buf, data, 1024*sizeof(float));
|
memcpy(buf, data, 1024 * sizeof(float));
|
||||||
_this->symDiag.releaseBuffer();
|
_this->symDiag.releaseBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +230,7 @@ private:
|
|||||||
dsp::stream<float> thrInput;
|
dsp::stream<float> thrInput;
|
||||||
dsp::Threshold thr;
|
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::Deframer deframe;
|
||||||
dsp::FalconRS falconRS;
|
dsp::FalconRS falconRS;
|
||||||
dsp::FalconPacketSync pkt;
|
dsp::FalconPacketSync pkt;
|
||||||
@ -243,7 +241,6 @@ private:
|
|||||||
VFOManager::VFO* vfo;
|
VFOManager::VFO* vfo;
|
||||||
|
|
||||||
ImGui::SymbolDiagram symDiag;
|
ImGui::SymbolDiagram symDiag;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MOD_EXPORT void _INIT_() {
|
MOD_EXPORT void _INIT_() {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include <base40.h>
|
#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
|
if (encoded >= 262144000000000) { // 40^9
|
||||||
*callsign = 0;
|
*callsign = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char *p = callsign;
|
char* p = callsign;
|
||||||
for (; encoded > 0; p++) {
|
for (; encoded > 0; p++) {
|
||||||
*p = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."[encoded % 40];
|
*p = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/."[encoded % 40];
|
||||||
encoded /= 40;
|
encoded /= 40;
|
||||||
|
@ -6,67 +6,57 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace mobilinkd
|
namespace mobilinkd {
|
||||||
{
|
|
||||||
|
|
||||||
template <uint16_t Poly = 0x5935, uint16_t Init = 0xFFFF>
|
template <uint16_t Poly = 0x5935, uint16_t Init = 0xFFFF>
|
||||||
struct CRC16
|
struct CRC16 {
|
||||||
{
|
static constexpr uint16_t MASK = 0xFFFF;
|
||||||
static constexpr uint16_t MASK = 0xFFFF;
|
static constexpr uint16_t LSB = 0x0001;
|
||||||
static constexpr uint16_t LSB = 0x0001;
|
static constexpr uint16_t MSB = 0x8000;
|
||||||
static constexpr uint16_t MSB = 0x8000;
|
|
||||||
|
|
||||||
uint16_t reg_ = Init;
|
uint16_t reg_ = Init;
|
||||||
|
|
||||||
void reset()
|
void reset() {
|
||||||
{
|
reg_ = Init;
|
||||||
reg_ = Init;
|
|
||||||
|
|
||||||
for (size_t i = 0; i != 16; ++i)
|
for (size_t i = 0; i != 16; ++i) {
|
||||||
{
|
auto bit = reg_ & LSB;
|
||||||
auto bit = reg_ & LSB;
|
if (bit) reg_ ^= Poly;
|
||||||
if (bit) reg_ ^= Poly;
|
reg_ >>= 1;
|
||||||
reg_ >>= 1;
|
if (bit) reg_ |= MSB;
|
||||||
if (bit) reg_ |= MSB;
|
}
|
||||||
|
|
||||||
|
reg_ &= MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_ &= MASK;
|
void operator()(uint8_t byte) {
|
||||||
}
|
reg_ = crc(byte, reg_);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return reg & MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t get()
|
uint16_t crc(uint8_t byte, uint16_t reg) {
|
||||||
{
|
for (size_t i = 0; i != 8; ++i) {
|
||||||
auto reg = reg_;
|
auto msb = reg & MSB;
|
||||||
for (size_t i = 0; i != 16; ++i)
|
reg = ((reg << 1) & MASK) | ((byte >> (7 - i)) & LSB);
|
||||||
{
|
if (msb) reg ^= Poly;
|
||||||
auto msb = reg & MSB;
|
}
|
||||||
reg = ((reg << 1) & MASK);
|
return reg & MASK;
|
||||||
if (msb) reg ^= Poly;
|
|
||||||
}
|
}
|
||||||
return reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<uint8_t, 2> get_bytes()
|
uint16_t get() {
|
||||||
{
|
auto reg = reg_;
|
||||||
auto crc = get();
|
for (size_t i = 0; i != 16; ++i) {
|
||||||
std::array<uint8_t, 2> result{uint8_t((crc >> 8) & 0xFF), uint8_t(crc & 0xFF)};
|
auto msb = reg & MSB;
|
||||||
return result;
|
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
|
} // mobilinkd
|
@ -10,224 +10,194 @@
|
|||||||
|
|
||||||
namespace mobilinkd {
|
namespace mobilinkd {
|
||||||
|
|
||||||
// Parts are adapted from:
|
// Parts are adapted from:
|
||||||
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
|
// http://aqdi.com/articles/using-the-golay-error-detection-and-correction-code-3/
|
||||||
|
|
||||||
namespace Golay24
|
namespace Golay24 {
|
||||||
{
|
|
||||||
|
|
||||||
int popcount(uint32_t n) {
|
int popcount(uint32_t n) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
count += ((n >> i) & 1);
|
count += ((n >> i) & 1);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail {
|
||||||
{
|
|
||||||
|
|
||||||
// Need a constexpr sort.
|
// Need a constexpr sort.
|
||||||
// https://stackoverflow.com/a/40030044/854133
|
// https://stackoverflow.com/a/40030044/854133
|
||||||
template<class T>
|
template <class T>
|
||||||
void swap(T& l, T& r)
|
void swap(T& l, T& r) {
|
||||||
{
|
T tmp = std::move(l);
|
||||||
T tmp = std::move(l);
|
l = std::move(r);
|
||||||
l = std::move(r);
|
r = std::move(tmp);
|
||||||
r = std::move(tmp);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
struct array
|
struct array {
|
||||||
{
|
constexpr T& operator[](size_t i) {
|
||||||
constexpr T& operator[](size_t i)
|
return arr[i];
|
||||||
{
|
}
|
||||||
return arr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const T& operator[](size_t i) const
|
constexpr const T& operator[](size_t i) const {
|
||||||
{
|
return arr[i];
|
||||||
return arr[i];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
constexpr const T* begin() const
|
constexpr const T* begin() const {
|
||||||
{
|
return arr;
|
||||||
return arr;
|
}
|
||||||
}
|
constexpr const T* end() const {
|
||||||
constexpr const T* end() const
|
return arr + N;
|
||||||
{
|
}
|
||||||
return arr + N;
|
|
||||||
}
|
|
||||||
|
|
||||||
T arr[N];
|
T arr[N];
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
void sort_impl(array<T, N> &array, size_t left, size_t right)
|
void sort_impl(array<T, N>& array, size_t left, size_t right) {
|
||||||
{
|
if (left < right) {
|
||||||
if (left < right)
|
size_t m = left;
|
||||||
{
|
|
||||||
size_t m = left;
|
|
||||||
|
|
||||||
for (size_t i = left + 1; i<right; i++)
|
for (size_t i = left + 1; i < right; i++)
|
||||||
if (array[i]<array[left])
|
if (array[i] < array[left])
|
||||||
swap(array[++m], array[i]);
|
swap(array[++m], array[i]);
|
||||||
|
|
||||||
swap(array[left], array[m]);
|
swap(array[left], array[m]);
|
||||||
|
|
||||||
sort_impl(array, left, m);
|
sort_impl(array, left, m);
|
||||||
sort_impl(array, m + 1, right);
|
sort_impl(array, m + 1, right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
array<T, N> sort(array<T, N> array)
|
array<T, N> sort(array<T, N> array) {
|
||||||
{
|
auto sorted = array;
|
||||||
auto sorted = array;
|
sort_impl(sorted, 0, N);
|
||||||
sort_impl(sorted, 0, N);
|
return sorted;
|
||||||
return sorted;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|
||||||
// static constexpr uint16_t POLY = 0xAE3;
|
// static constexpr uint16_t POLY = 0xAE3;
|
||||||
constexpr uint16_t POLY = 0xC75;
|
constexpr uint16_t POLY = 0xC75;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct SyndromeMapEntry
|
struct SyndromeMapEntry {
|
||||||
{
|
uint32_t a{ 0 };
|
||||||
uint32_t a{0};
|
uint16_t b{ 0 };
|
||||||
uint16_t b{0};
|
};
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the syndrome of a [23,12] Golay codeword.
|
* Calculate the syndrome of a [23,12] Golay codeword.
|
||||||
*
|
*
|
||||||
* @return the 11-bit syndrome of the codeword in bits [22:12].
|
* @return the 11-bit syndrome of the codeword in bits [22:12].
|
||||||
*/
|
*/
|
||||||
uint32_t syndrome(uint32_t codeword)
|
uint32_t syndrome(uint32_t codeword) {
|
||||||
{
|
codeword &= 0xffffffl;
|
||||||
codeword &= 0xffffffl;
|
for (size_t i = 0; i != 12; ++i) {
|
||||||
for (size_t i = 0; i != 12; ++i)
|
if (codeword & 1)
|
||||||
{
|
codeword ^= POLY;
|
||||||
if (codeword & 1)
|
codeword >>= 1;
|
||||||
codeword ^= POLY;
|
}
|
||||||
codeword >>= 1;
|
return (codeword << 12);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i != VECLEN - 2; ++i)
|
bool parity(uint32_t codeword) {
|
||||||
{
|
return popcount(codeword) & 1;
|
||||||
for (size_t j = i + 1; j != VECLEN - 1; ++j)
|
}
|
||||||
{
|
|
||||||
for (size_t k = j + 1; k != VECLEN; ++k)
|
SyndromeMapEntry makeSyndromeMapEntry(uint64_t val) {
|
||||||
{
|
return SyndromeMapEntry{ uint32_t(val >> 16), uint16_t(val & 0xFFFF) };
|
||||||
auto v = (1 << i) | (1 << j) | (1 << k);
|
}
|
||||||
|
|
||||||
|
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);
|
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.
|
* Calculate [23,12] Golay codeword.
|
||||||
*
|
*
|
||||||
* @return checkbits(11)|data(12).
|
* @return checkbits(11)|data(12).
|
||||||
*/
|
*/
|
||||||
uint32_t encode23(uint16_t data)
|
uint32_t encode23(uint16_t data) {
|
||||||
{
|
// data &= 0xfff;
|
||||||
// data &= 0xfff;
|
uint32_t codeword = data;
|
||||||
uint32_t codeword = data;
|
for (size_t i = 0; i != 12; ++i) {
|
||||||
for (size_t i = 0; i != 12; ++i)
|
if (codeword & 1)
|
||||||
{
|
codeword ^= POLY;
|
||||||
if (codeword & 1)
|
codeword >>= 1;
|
||||||
codeword ^= POLY;
|
}
|
||||||
codeword >>= 1;
|
return codeword | (data << 11);
|
||||||
}
|
}
|
||||||
return codeword | (data << 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t encode24(uint16_t data)
|
uint32_t encode24(uint16_t data) {
|
||||||
{
|
auto codeword = encode23(data);
|
||||||
auto codeword = encode23(data);
|
return ((codeword << 1) | parity(codeword));
|
||||||
return ((codeword << 1) | parity(codeword));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool decode(uint32_t input, uint32_t& output)
|
bool decode(uint32_t input, uint32_t& output) {
|
||||||
{
|
auto syndrm = syndrome(input >> 1);
|
||||||
auto syndrm = syndrome(input >> 1);
|
auto it = std::lower_bound(LUT.begin(), LUT.end(), syndrm,
|
||||||
auto it = std::lower_bound(LUT.begin(), LUT.end(), syndrm,
|
[](const SyndromeMapEntry& sme, uint32_t val) {
|
||||||
[](const SyndromeMapEntry& sme, uint32_t val){
|
return (sme.a >> 8) < val;
|
||||||
return (sme.a >> 8) < val;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if ((it->a >> 8) == syndrm)
|
if ((it->a >> 8) == syndrm) {
|
||||||
{
|
// Build the correction from the compressed entry.
|
||||||
// Build the correction from the compressed entry.
|
auto correction = ((((it->a & 0xFF) << 16) | it->b) << 1);
|
||||||
auto correction = ((((it->a & 0xFF) << 16) | it->b) << 1);
|
// Apply the correction to the input.
|
||||||
// Apply the correction to the input.
|
output = input ^ correction;
|
||||||
output = input ^ correction;
|
// Only test parity for 3-bit errors.
|
||||||
// Only test parity for 3-bit errors.
|
return popcount(syndrm) < 3 || !parity(output);
|
||||||
return popcount(syndrm) < 3 || !parity(output);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Golay24
|
} // Golay24
|
||||||
|
|
||||||
} // mobilinkd
|
} // mobilinkd
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user