mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-06-28 21:37:50 +02:00
Fixed resampling bug + added waterfall colormap selection + general bugfix
This commit is contained in:
49
core/src/gui/colormaps.cpp
Normal file
49
core/src/gui/colormaps.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <gui/colormaps.h>
|
||||
#include <filesystem>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <fstream>
|
||||
#include <json.hpp>
|
||||
|
||||
using nlohmann::json;
|
||||
|
||||
namespace colormaps {
|
||||
std::map<std::string, Map> maps;
|
||||
|
||||
void loadMap(std::string path) {
|
||||
if (!std::filesystem::is_regular_file(path)) {
|
||||
spdlog::error("Could not load {0}, file doesn't exist", path);
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream file(path.c_str());
|
||||
json data;
|
||||
file >> data;
|
||||
file.close();
|
||||
|
||||
Map map;
|
||||
std::vector<std::string> mapTxt;
|
||||
|
||||
try {
|
||||
map.name = data["name"];
|
||||
map.author = data["author"];
|
||||
mapTxt = data["map"].get<std::vector<std::string>>();
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
spdlog::error("Could not load {0}", path);
|
||||
return;
|
||||
}
|
||||
|
||||
map.entryCount = mapTxt.size();
|
||||
map.map = new float[mapTxt.size() * 3];
|
||||
int i = 0;
|
||||
for(auto const& col : mapTxt) {
|
||||
uint8_t r, g, b, a;
|
||||
map.map[i * 3] = std::stoi(col.substr(1, 2), NULL, 16);
|
||||
map.map[(i * 3) + 1] = std::stoi(col.substr(3, 2), NULL, 16);
|
||||
map.map[(i * 3) + 2] = std::stoi(col.substr(5, 2), NULL, 16);
|
||||
i++;
|
||||
}
|
||||
|
||||
maps[map.name] = map;
|
||||
}
|
||||
}
|
18
core/src/gui/colormaps.h
Normal file
18
core/src/gui/colormaps.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <module.h>
|
||||
#include <map>
|
||||
|
||||
namespace colormaps {
|
||||
struct Map {
|
||||
std::string name;
|
||||
std::string author;
|
||||
float* map;
|
||||
int entryCount;
|
||||
};
|
||||
|
||||
void loadMap(std::string path);
|
||||
|
||||
SDRPP_EXPORT std::map<std::string, Map> maps;
|
||||
}
|
@ -31,6 +31,7 @@
|
||||
#include <signal_path/source.h>
|
||||
#include <gui/dialogs/loading_screen.h>
|
||||
#include <options.h>
|
||||
#include <gui/colormaps.h>
|
||||
|
||||
// const int FFTSizes[] = {
|
||||
// 65536,
|
||||
@ -121,6 +122,7 @@ void windowInit() {
|
||||
core::configManager.aquire();
|
||||
gui::menu.order = core::configManager.conf["menuOrder"].get<std::vector<std::string>>();
|
||||
std::string modulesDir = core::configManager.conf["modulesDirectory"];
|
||||
std::string resourcesDir = core::configManager.conf["resourcesDirectory"];
|
||||
core::configManager.release();
|
||||
|
||||
gui::menu.registerEntry("Source", sourecmenu::draw, NULL);
|
||||
@ -181,6 +183,27 @@ void windowInit() {
|
||||
core::moduleManager.createInstance(name, module);
|
||||
}
|
||||
|
||||
// Load color maps
|
||||
LoadingScreen::show("Loading color maps");
|
||||
spdlog::info("Loading color maps");
|
||||
if (std::filesystem::is_directory(resourcesDir + "/colormaps")) {
|
||||
for (const auto & file : std::filesystem::directory_iterator(resourcesDir + "/colormaps")) {
|
||||
std::string path = file.path().generic_string();
|
||||
LoadingScreen::show("Loading " + path);
|
||||
spdlog::info("Loading {0}", path);
|
||||
if (file.path().extension().generic_string() != ".json") {
|
||||
continue;
|
||||
}
|
||||
if (!file.is_regular_file()) { continue; }
|
||||
colormaps::loadMap(path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
spdlog::warn("Color map directory {0} does not exist, not loading modules from directory", modulesDir);
|
||||
}
|
||||
|
||||
gui::waterfall.updatePalletteFromArray(colormaps::maps["Turbo"].map, colormaps::maps["Turbo"].entryCount);
|
||||
|
||||
sourecmenu::init();
|
||||
sinkmenu::init();
|
||||
scriptingmenu::init();
|
||||
|
@ -2,21 +2,58 @@
|
||||
#include <imgui.h>
|
||||
#include <gui/gui.h>
|
||||
#include <core.h>
|
||||
#include <gui/colormaps.h>
|
||||
#include <gui/gui.h>
|
||||
|
||||
namespace displaymenu {
|
||||
bool showWaterfall;
|
||||
int colorMapId = 0;
|
||||
std::vector<std::string> colorMapNames;
|
||||
std::string colorMapNamesTxt = "";
|
||||
std::string colorMapAuthor = "";
|
||||
|
||||
void init() {
|
||||
showWaterfall = core::configManager.conf["showWaterfall"];
|
||||
showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall();
|
||||
std::string colormapName = core::configManager.conf["colorMap"];
|
||||
if (colormaps::maps.find(colormapName) != colormaps::maps.end()) {
|
||||
colormaps::Map map = colormaps::maps[colormapName];
|
||||
gui::waterfall.updatePalletteFromArray(map.map, map.entryCount);
|
||||
}
|
||||
|
||||
for (auto const& [name, map] : colormaps::maps) {
|
||||
colorMapNames.push_back(name);
|
||||
colorMapNamesTxt += name;
|
||||
colorMapNamesTxt += '\0';
|
||||
if (name == colormapName) {
|
||||
colorMapId = (colorMapNames.size() - 1);
|
||||
colorMapAuthor = map.author;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw(void* ctx) {
|
||||
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
||||
if (ImGui::Checkbox("Show Waterfall", &showWaterfall)) {
|
||||
showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall();
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["showWaterfall"] = showWaterfall;
|
||||
core::configManager.release(true);
|
||||
}
|
||||
|
||||
if (colorMapNames.size() > 0) {
|
||||
ImGui::Text("Color Map");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||
if (ImGui::Combo("##_sdrpp_color_map_sel", &colorMapId, colorMapNamesTxt.c_str())) {
|
||||
colormaps::Map map = colormaps::maps[colorMapNames[colorMapId]];
|
||||
gui::waterfall.updatePalletteFromArray(map.map, map.entryCount);
|
||||
core::configManager.aquire();
|
||||
core::configManager.conf["colorMap"] = colorMapNames[colorMapId];
|
||||
core::configManager.release(true);
|
||||
colorMapAuthor = map.author;
|
||||
}
|
||||
ImGui::Text("Color map Author: %s", colorMapAuthor.c_str());
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
float COLOR_MAP[][3] = {
|
||||
float DEFAULT_COLOR_MAP[][3] = {
|
||||
{0x00, 0x00, 0x20},
|
||||
{0x00, 0x00, 0x30},
|
||||
{0x00, 0x00, 0x50},
|
||||
@ -106,7 +106,7 @@ namespace ImGui {
|
||||
viewBandwidth = 1.0;
|
||||
wholeBandwidth = 1.0;
|
||||
|
||||
updatePallette(COLOR_MAP, 13);
|
||||
updatePallette(DEFAULT_COLOR_MAP, 13);
|
||||
}
|
||||
|
||||
void WaterFall::init() {
|
||||
@ -568,6 +568,7 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
void WaterFall::updatePallette(float colors[][3], int colorCount) {
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
for (int i = 0; i < WATERFALL_RESOLUTION; i++) {
|
||||
int lowerId = floorf(((float)i / (float)WATERFALL_RESOLUTION) * colorCount);
|
||||
int upperId = ceilf(((float)i / (float)WATERFALL_RESOLUTION) * colorCount);
|
||||
@ -579,6 +580,23 @@ namespace ImGui {
|
||||
float b = (colors[lowerId][2] * (1.0 - ratio)) + (colors[upperId][2] * (ratio));
|
||||
waterfallPallet[i] = ((uint32_t)255 << 24) | ((uint32_t)b << 16) | ((uint32_t)g << 8) | (uint32_t)r;
|
||||
}
|
||||
updateWaterfallFb();
|
||||
}
|
||||
|
||||
void WaterFall::updatePalletteFromArray(float* colors, int colorCount) {
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
for (int i = 0; i < WATERFALL_RESOLUTION; i++) {
|
||||
int lowerId = floorf(((float)i / (float)WATERFALL_RESOLUTION) * colorCount);
|
||||
int upperId = ceilf(((float)i / (float)WATERFALL_RESOLUTION) * colorCount);
|
||||
lowerId = std::clamp<int>(lowerId, 0, colorCount - 1);
|
||||
upperId = std::clamp<int>(upperId, 0, colorCount - 1);
|
||||
float ratio = (((float)i / (float)WATERFALL_RESOLUTION) * colorCount) - lowerId;
|
||||
float r = (colors[(lowerId * 3) + 0] * (1.0 - ratio)) + (colors[(upperId * 3) + 0] * (ratio));
|
||||
float g = (colors[(lowerId * 3) + 1] * (1.0 - ratio)) + (colors[(upperId * 3) + 1] * (ratio));
|
||||
float b = (colors[(lowerId * 3) + 2] * (1.0 - ratio)) + (colors[(upperId * 3) + 2] * (ratio));
|
||||
waterfallPallet[i] = ((uint32_t)255 << 24) | ((uint32_t)b << 16) | ((uint32_t)g << 8) | (uint32_t)r;
|
||||
}
|
||||
updateWaterfallFb();
|
||||
}
|
||||
|
||||
void WaterFall::autoRange() {
|
||||
@ -627,6 +645,7 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
void WaterFall::setViewBandwidth(double bandWidth) {
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
if (bandWidth == viewBandwidth) {
|
||||
return;
|
||||
}
|
||||
@ -651,6 +670,7 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
void WaterFall::setViewOffset(double offset) {
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
if (offset == viewOffset) {
|
||||
return;
|
||||
}
|
||||
@ -690,6 +710,7 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
void WaterFall::setWaterfallMin(float min) {
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
if (min == waterfallMin) {
|
||||
return;
|
||||
}
|
||||
@ -702,6 +723,7 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
void WaterFall::setWaterfallMax(float max) {
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
if (max == waterfallMax) {
|
||||
return;
|
||||
}
|
||||
@ -720,7 +742,7 @@ namespace ImGui {
|
||||
}
|
||||
|
||||
void WaterFall::setRawFFTSize(int size, bool lock) {
|
||||
if (lock) { buf_mtx.lock(); }
|
||||
std::lock_guard<std::mutex> lck(buf_mtx);
|
||||
rawFFTSize = size;
|
||||
if (rawFFTs != NULL) {
|
||||
rawFFTs = (float*)realloc(rawFFTs, rawFFTSize * waterfallHeight * sizeof(float));
|
||||
@ -729,7 +751,6 @@ namespace ImGui {
|
||||
rawFFTs = (float*)malloc(rawFFTSize * waterfallHeight * sizeof(float));
|
||||
}
|
||||
memset(rawFFTs, 0, rawFFTSize * waterfallHeight * sizeof(float));
|
||||
if (lock) { buf_mtx.unlock(); }
|
||||
}
|
||||
|
||||
void WaterfallVFO::setOffset(double offset) {
|
||||
|
@ -57,6 +57,7 @@ namespace ImGui {
|
||||
void pushFFT();
|
||||
|
||||
void updatePallette(float colors[][3], int colorCount);
|
||||
void updatePalletteFromArray(float* colors, int colorCount);
|
||||
|
||||
void setCenterFrequency(double freq);
|
||||
double getCenterFrequency();
|
||||
|
Reference in New Issue
Block a user