mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-01-24 00:34:44 +01:00
More fixes
This commit is contained in:
parent
51ee02f9da
commit
48a8b04eaa
@ -1,62 +1,73 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
namespace config {
|
ConfigManager::ConfigManager() {
|
||||||
bool configModified = false;
|
|
||||||
json config;
|
|
||||||
bool autoSaveRunning = false;
|
|
||||||
std::string _path;
|
|
||||||
std::thread _workerThread;
|
|
||||||
std::string rootDir;
|
|
||||||
|
|
||||||
void _autoSaveWorker() {
|
|
||||||
while (autoSaveRunning) {
|
|
||||||
if (configModified) {
|
|
||||||
configModified = false;
|
|
||||||
std::ofstream file(_path.c_str());
|
|
||||||
file << std::setw(4) << config;
|
|
||||||
file.close();
|
|
||||||
spdlog::info("Config saved");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigManager::setPath(std::string file) {
|
||||||
|
path = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::load(json default, bool lock) {
|
||||||
|
if (lock) { mtx.lock(); }
|
||||||
|
if (path == "") {
|
||||||
|
spdlog::error("Config manager tried to load file with no path specified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!std::filesystem::exists(path)) {
|
||||||
|
spdlog::warn("Config file '{0}' does not exist, creating it", path);
|
||||||
|
conf = default;
|
||||||
|
save(false);
|
||||||
|
}
|
||||||
|
if (!std::filesystem::is_regular_file(path)) {
|
||||||
|
spdlog::error("Config file '{0}' isn't a file", path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file(path.c_str());
|
||||||
|
file >> conf;
|
||||||
|
file.close();
|
||||||
|
if (lock) { mtx.unlock(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::save(bool lock) {
|
||||||
|
if (lock) { mtx.lock(); }
|
||||||
|
std::ofstream file(path.c_str());
|
||||||
|
file << conf.dump(4);
|
||||||
|
file.close();
|
||||||
|
if (lock) { mtx.unlock(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::enableAutoSave() {
|
||||||
|
autoSaveEnabled = true;
|
||||||
|
autoSaveThread = std::thread(autoSaveWorker, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::disableAutoSave() {
|
||||||
|
autoSaveEnabled = false;
|
||||||
|
autoSaveThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::aquire() {
|
||||||
|
mtx.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::release(bool changed) {
|
||||||
|
this->changed |= changed;
|
||||||
|
mtx.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigManager::autoSaveWorker(ConfigManager* _this) {
|
||||||
|
while (_this->autoSaveEnabled) {
|
||||||
|
if (!_this->mtx.try_lock()) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (_this->changed) {
|
||||||
|
_this->changed = false;
|
||||||
|
_this->save(false);
|
||||||
|
}
|
||||||
|
_this->mtx.unlock();
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(std::string path) {
|
|
||||||
if (!std::filesystem::exists(path)) {
|
|
||||||
spdlog::error("Config file does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!std::filesystem::is_regular_file(path)) {
|
|
||||||
spdlog::error("Config file isn't a file...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_path = path;
|
|
||||||
std::ifstream file(path.c_str());
|
|
||||||
file >> config;
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void startAutoSave() {
|
|
||||||
if (autoSaveRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
autoSaveRunning = true;
|
|
||||||
_workerThread = std::thread(_autoSaveWorker);
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopAutoSave() {
|
|
||||||
if (!autoSaveRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
autoSaveRunning = false;
|
|
||||||
_workerThread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setRootDirectory(std::string dir) {
|
|
||||||
rootDir = dir;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getRootDirectory() {
|
|
||||||
return rootDir;
|
|
||||||
}
|
|
||||||
};
|
|
@ -7,16 +7,42 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using nlohmann::json;
|
using nlohmann::json;
|
||||||
|
|
||||||
namespace config {
|
//#define DEV_BUILD
|
||||||
void load(std::string path);
|
|
||||||
void startAutoSave();
|
#ifndef ROOT_DIR
|
||||||
void stopAutoSave();
|
#ifdef DEV_BUILD
|
||||||
void setRootDirectory(std::string dir);
|
#define ROOT_DIR "../root_dev"
|
||||||
std::string getRootDirectory();
|
#elif _WIN32
|
||||||
|
#define ROOT_DIR "."
|
||||||
|
#else
|
||||||
|
#define ROOT_DIR "/etc/sdrpp"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ConfigManager {
|
||||||
|
public:
|
||||||
|
ConfigManager();
|
||||||
|
void setPath(std::string file);
|
||||||
|
void load(json default, bool lock = true);
|
||||||
|
void save(bool lock = true);
|
||||||
|
void enableAutoSave();
|
||||||
|
void disableAutoSave();
|
||||||
|
void aquire();
|
||||||
|
void release(bool changed = false);
|
||||||
|
|
||||||
|
json conf;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void autoSaveWorker(ConfigManager* _this);
|
||||||
|
|
||||||
|
std::string path = "";
|
||||||
|
bool changed = false;
|
||||||
|
bool autoSaveEnabled = false;
|
||||||
|
std::thread autoSaveThread;
|
||||||
|
std::mutex mtx;
|
||||||
|
|
||||||
extern bool configModified;
|
|
||||||
extern json config;
|
|
||||||
};
|
};
|
@ -13,6 +13,7 @@
|
|||||||
#include <module.h>
|
#include <module.h>
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <core.h>
|
||||||
|
|
||||||
#include <dsp/block.h>
|
#include <dsp/block.h>
|
||||||
|
|
||||||
@ -23,8 +24,9 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Comment to build a normal release
|
namespace core {
|
||||||
#define DEV_BUILD
|
ConfigManager configManager;
|
||||||
|
};
|
||||||
|
|
||||||
bool maximized = false;
|
bool maximized = false;
|
||||||
bool fullScreen = false;
|
bool fullScreen = false;
|
||||||
@ -50,18 +52,11 @@ int sdrpp_main() {
|
|||||||
|
|
||||||
spdlog::info("SDR++ v" VERSION_STR);
|
spdlog::info("SDR++ v" VERSION_STR);
|
||||||
|
|
||||||
#ifdef DEV_BUILD
|
|
||||||
config::setRootDirectory("../root_dev");
|
|
||||||
#elif _WIN32
|
|
||||||
config::setRootDirectory(".");
|
|
||||||
#else
|
|
||||||
config::setRootDirectory("/etc/sdrpp");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
spdlog::info("Loading config");
|
spdlog::info("Loading config");
|
||||||
config::load(config::getRootDirectory() + "/config.json");
|
core::configManager.setPath(ROOT_DIR "/config.json");
|
||||||
config::startAutoSave();
|
core::configManager.load(json());
|
||||||
|
core::configManager.enableAutoSave();
|
||||||
|
|
||||||
// Setup window
|
// Setup window
|
||||||
glfwSetErrorCallback(glfw_error_callback);
|
glfwSetErrorCallback(glfw_error_callback);
|
||||||
@ -74,9 +69,11 @@ int sdrpp_main() {
|
|||||||
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
|
||||||
|
|
||||||
int winWidth = config::config["windowSize"]["w"];
|
core::configManager.aquire();
|
||||||
int winHeight = config::config["windowSize"]["h"];
|
int winWidth = core::configManager.conf["windowSize"]["w"];
|
||||||
maximized = config::config["maximized"];
|
int winHeight = core::configManager.conf["windowSize"]["h"];
|
||||||
|
maximized = core::configManager.conf["maximized"];
|
||||||
|
core::configManager.release();
|
||||||
|
|
||||||
// Create window with graphics context
|
// Create window with graphics context
|
||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
@ -94,7 +91,7 @@ int sdrpp_main() {
|
|||||||
|
|
||||||
// Load app icon
|
// Load app icon
|
||||||
GLFWimage icons[10];
|
GLFWimage icons[10];
|
||||||
icons[0].pixels = stbi_load((config::getRootDirectory() + "/res/icons/sdrpp.png").c_str(), &icons[0].width, &icons[0].height, 0, 4);
|
icons[0].pixels = stbi_load(((std::string)(ROOT_DIR "/res/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[1].width = icons[1].height = 16;
|
||||||
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4); icons[2].width = icons[2].height = 24;
|
icons[2].pixels = (unsigned char*)malloc(24 * 24 * 4); icons[2].width = icons[2].height = 24;
|
||||||
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4); icons[3].width = icons[3].height = 32;
|
icons[3].pixels = (unsigned char*)malloc(32 * 32 * 4); icons[3].width = icons[3].height = 32;
|
||||||
@ -162,10 +159,10 @@ int sdrpp_main() {
|
|||||||
icons::load();
|
icons::load();
|
||||||
|
|
||||||
spdlog::info("Loading band plans");
|
spdlog::info("Loading band plans");
|
||||||
bandplan::loadFromDir(config::getRootDirectory() + "/bandplans");
|
bandplan::loadFromDir(ROOT_DIR "/bandplans");
|
||||||
|
|
||||||
spdlog::info("Loading band plans color table");
|
spdlog::info("Loading band plans color table");
|
||||||
bandplan::loadColorTable(config::getRootDirectory() + "/band_colors.json");
|
bandplan::loadColorTable(ROOT_DIR "/band_colors.json");
|
||||||
|
|
||||||
windowInit();
|
windowInit();
|
||||||
|
|
||||||
@ -185,11 +182,12 @@ int sdrpp_main() {
|
|||||||
|
|
||||||
if (_maximized != maximized) {
|
if (_maximized != maximized) {
|
||||||
_maximized = maximized;
|
_maximized = maximized;
|
||||||
config::config["maximized"]= _maximized;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["maximized"]= _maximized;
|
||||||
if (!maximized) {
|
if (!maximized) {
|
||||||
glfwSetWindowSize(window, config::config["windowSize"]["w"], config::config["windowSize"]["h"]);
|
glfwSetWindowSize(window, core::configManager.conf["windowSize"]["w"], core::configManager.conf["windowSize"]["h"]);
|
||||||
}
|
}
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _winWidth, _winHeight;
|
int _winWidth, _winHeight;
|
||||||
@ -214,9 +212,10 @@ int sdrpp_main() {
|
|||||||
if ((_winWidth != winWidth || _winHeight != winHeight) && !maximized && _winWidth > 0 && _winHeight > 0) {
|
if ((_winWidth != winWidth || _winHeight != winHeight) && !maximized && _winWidth > 0 && _winHeight > 0) {
|
||||||
winWidth = _winWidth;
|
winWidth = _winWidth;
|
||||||
winHeight = _winHeight;
|
winHeight = _winHeight;
|
||||||
config::config["windowSize"]["w"] = winWidth;
|
core::configManager.aquire();
|
||||||
config::config["windowSize"]["h"] = winHeight;
|
core::configManager.conf["windowSize"]["w"] = winWidth;
|
||||||
config::configModified = true;
|
core::configManager.conf["windowSize"]["h"] = winHeight;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (winWidth > 0 && winHeight > 0) {
|
if (winWidth > 0 && winHeight > 0) {
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <module.h>
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
SDRPP_EXPORT ConfigManager configManager;
|
||||||
|
};
|
||||||
|
|
||||||
int sdrpp_main();
|
int sdrpp_main();
|
@ -9,7 +9,7 @@ FrequencySelect::FrequencySelect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FrequencySelect::init() {
|
void FrequencySelect::init() {
|
||||||
font = ImGui::GetIO().Fonts->AddFontFromFileTTF((config::getRootDirectory() + "/res/fonts/Roboto-Medium.ttf").c_str(), 42.0f);
|
font = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(ROOT_DIR "/res/fonts/Roboto-Medium.ttf")).c_str(), 42.0f);
|
||||||
for (int i = 0; i < 12; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
digits[i] = 0;
|
digits[i] = 0;
|
||||||
|
|
||||||
|
@ -3,4 +3,5 @@
|
|||||||
namespace gui {
|
namespace gui {
|
||||||
ImGui::WaterFall waterfall;
|
ImGui::WaterFall waterfall;
|
||||||
FrequencySelect freqSelect;
|
FrequencySelect freqSelect;
|
||||||
|
Menu menu;
|
||||||
};
|
};
|
@ -1,9 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <gui/waterfall.h>
|
#include <gui/waterfall.h>
|
||||||
#include <gui/frequency_select.h>
|
#include <gui/frequency_select.h>
|
||||||
|
#include <gui/menu.h>
|
||||||
#include <module.h>
|
#include <module.h>
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
SDRPP_EXPORT ImGui::WaterFall waterfall;
|
SDRPP_EXPORT ImGui::WaterFall waterfall;
|
||||||
SDRPP_EXPORT FrequencySelect freqSelect;
|
SDRPP_EXPORT FrequencySelect freqSelect;
|
||||||
|
SDRPP_EXPORT Menu menu;
|
||||||
};
|
};
|
@ -24,9 +24,9 @@ namespace icons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void load() {
|
void load() {
|
||||||
LOGO = (ImTextureID)(uintptr_t)loadTexture(config::getRootDirectory() + "/res/icons/sdrpp.png");
|
LOGO = (ImTextureID)(uintptr_t)loadTexture(ROOT_DIR "/res/icons/sdrpp.png");
|
||||||
PLAY = (ImTextureID)(uintptr_t)loadTexture(config::getRootDirectory() + "/res/icons/play.png");
|
PLAY = (ImTextureID)(uintptr_t)loadTexture(ROOT_DIR "/res/icons/play.png");
|
||||||
STOP = (ImTextureID)(uintptr_t)loadTexture(config::getRootDirectory() + "/res/icons/stop.png");
|
STOP = (ImTextureID)(uintptr_t)loadTexture(ROOT_DIR "/res/icons/stop.png");
|
||||||
MENU = (ImTextureID)(uintptr_t)loadTexture(config::getRootDirectory() + "/res/icons/menu.png");
|
MENU = (ImTextureID)(uintptr_t)loadTexture(ROOT_DIR "/res/icons/menu.png");
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,6 @@ namespace icons {
|
|||||||
extern ImTextureID STOP;
|
extern ImTextureID STOP;
|
||||||
extern ImTextureID MENU;
|
extern ImTextureID MENU;
|
||||||
|
|
||||||
GLuint loadTexture(char* path);
|
GLuint loadTexture(std::string path);
|
||||||
void load();
|
void load();
|
||||||
}
|
}
|
@ -64,14 +64,14 @@ bool showMenu = true;
|
|||||||
void saveCurrentSource() {
|
void saveCurrentSource() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (std::string gainName : soapy.gainList) {
|
for (std::string gainName : soapy.gainList) {
|
||||||
config::config["sourceSettings"][sourceName]["gains"][gainName] = uiGains[i];
|
core::configManager.conf["sourceSettings"][sourceName]["gains"][gainName] = uiGains[i];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
config::config["sourceSettings"][sourceName]["sampleRate"] = soapy.sampleRates[srId];
|
core::configManager.conf["sourceSettings"][sourceName]["sampleRate"] = soapy.sampleRates[srId];
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSourceConfig(std::string name) {
|
void loadSourceConfig(std::string name) {
|
||||||
json sourceSettings = config::config["sourceSettings"][name];
|
json sourceSettings = core::configManager.conf["sourceSettings"][name];
|
||||||
|
|
||||||
sampleRate = sourceSettings["sampleRate"];
|
sampleRate = sourceSettings["sampleRate"];
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ void loadSourceConfig(std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadAudioConfig(std::string name) {
|
void loadAudioConfig(std::string name) {
|
||||||
json audioSettings = config::config["audio"][name];
|
json audioSettings = core::configManager.conf["audio"][name];
|
||||||
std::string devName = audioSettings["device"];
|
std::string devName = audioSettings["device"];
|
||||||
auto _devIt = std::find(audio::streams[name]->audio->deviceNames.begin(), audio::streams[name]->audio->deviceNames.end(), devName);
|
auto _devIt = std::find(audio::streams[name]->audio->deviceNames.begin(), audio::streams[name]->audio->deviceNames.end(), devName);
|
||||||
|
|
||||||
@ -146,15 +146,126 @@ void loadAudioConfig(std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void saveAudioConfig(std::string name) {
|
void saveAudioConfig(std::string name) {
|
||||||
config::config["audio"][name]["device"] = audio::streams[name]->audio->deviceNames[audio::streams[name]->deviceId];
|
core::configManager.conf["audio"][name]["device"] = audio::streams[name]->audio->deviceNames[audio::streams[name]->deviceId];
|
||||||
config::config["audio"][name]["volume"] = audio::streams[name]->volume;
|
core::configManager.conf["audio"][name]["volume"] = audio::streams[name]->volume;
|
||||||
config::config["audio"][name]["sampleRate"] = audio::streams[name]->sampleRate;
|
core::configManager.conf["audio"][name]["sampleRate"] = audio::streams[name]->sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setVFO(float freq);
|
||||||
|
|
||||||
|
// =======================================================
|
||||||
|
|
||||||
|
void sourceMenu(void* ctx) {
|
||||||
|
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
|
||||||
|
if (playing) { style::beginDisabled(); };
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(menuColumnWidth);
|
||||||
|
if (ImGui::Combo("##_0_", &devId, soapy.txtDevList.c_str())) {
|
||||||
|
spdlog::info("Changed input device: {0}", devId);
|
||||||
|
sourceName = soapy.devNameList[devId];
|
||||||
|
soapy.setDevice(soapy.devList[devId]);
|
||||||
|
|
||||||
|
core::configManager.aquire();
|
||||||
|
if (core::configManager.conf["sourceSettings"].contains(sourceName)) {
|
||||||
|
loadSourceConfig(sourceName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
srId = 0;
|
||||||
|
sampleRate = soapy.getSampleRate();
|
||||||
|
bw.val = sampleRate;
|
||||||
|
gui::waterfall.setBandwidth(sampleRate);
|
||||||
|
gui::waterfall.setViewBandwidth(sampleRate);
|
||||||
|
sigpath::signalPath.setSampleRate(sampleRate);
|
||||||
|
|
||||||
|
if (soapy.gainList.size() >= 0) {
|
||||||
|
delete[] uiGains;
|
||||||
|
uiGains = new float[soapy.gainList.size()];
|
||||||
|
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||||
|
uiGains[i] = soapy.currentGains[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setVFO(gui::freqSelect.frequency);
|
||||||
|
core::configManager.conf["source"] = sourceName;
|
||||||
|
core::configManager.release(true);
|
||||||
|
}
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
if (ImGui::Combo("##_1_", &srId, soapy.txtSampleRateList.c_str())) {
|
||||||
|
spdlog::info("Changed sample rate: {0}", srId);
|
||||||
|
sampleRate = soapy.sampleRates[srId];
|
||||||
|
soapy.setSampleRate(sampleRate);
|
||||||
|
gui::waterfall.setBandwidth(sampleRate);
|
||||||
|
gui::waterfall.setViewBandwidth(sampleRate);
|
||||||
|
sigpath::signalPath.setSampleRate(sampleRate);
|
||||||
|
bw.val = sampleRate;
|
||||||
|
|
||||||
|
core::configManager.aquire();
|
||||||
|
if (!core::configManager.conf["sourceSettings"].contains(sourceName)) {
|
||||||
|
saveCurrentSource();
|
||||||
|
}
|
||||||
|
core::configManager.conf["sourceSettings"][sourceName]["sampleRate"] = sampleRate;
|
||||||
|
core::configManager.release(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
bool noDevice = (soapy.devList.size() == 0);
|
||||||
|
if (ImGui::Button("Refresh", ImVec2(menuColumnWidth - ImGui::GetCursorPosX(), 0.0f))) {
|
||||||
|
soapy.refresh();
|
||||||
|
if (noDevice && soapy.devList.size() > 0) {
|
||||||
|
sourceName = soapy.devNameList[0];
|
||||||
|
soapy.setDevice(soapy.devList[0]);
|
||||||
|
if (core::configManager.conf["sourceSettings"][sourceName]) {
|
||||||
|
loadSourceConfig(sourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playing) { style::endDisabled(); };
|
||||||
|
|
||||||
|
float maxTextLength = 0;
|
||||||
|
float txtLen = 0;
|
||||||
|
char buf[100];
|
||||||
|
|
||||||
|
// Calculate the spacing
|
||||||
|
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||||
|
sprintf(buf, "%s gain", soapy.gainList[i].c_str());
|
||||||
|
txtLen = ImGui::CalcTextSize(buf).x;
|
||||||
|
if (txtLen > maxTextLength) {
|
||||||
|
maxTextLength = txtLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < soapy.gainList.size(); i++) {
|
||||||
|
ImGui::Text("%s gain", soapy.gainList[i].c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
sprintf(buf, "##_gain_slide_%d_", i);
|
||||||
|
|
||||||
|
ImGui::SetCursorPosX(maxTextLength + 5);
|
||||||
|
ImGui::PushItemWidth(menuColumnWidth - (maxTextLength + 5));
|
||||||
|
if (ImGui::SliderFloat(buf, &uiGains[i], soapy.gainRanges[i].minimum(), soapy.gainRanges[i].maximum())) {
|
||||||
|
soapy.setGain(i, uiGains[i]);
|
||||||
|
core::configManager.aquire();
|
||||||
|
if (!core::configManager.conf["sourceSettings"].contains(sourceName)) {
|
||||||
|
saveCurrentSource();
|
||||||
|
}
|
||||||
|
core::configManager.conf["sourceSettings"][sourceName]["gains"][soapy.gainList[i]] = uiGains[i];
|
||||||
|
core::configManager.release(true);
|
||||||
|
}
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================
|
||||||
|
|
||||||
void windowInit() {
|
void windowInit() {
|
||||||
spdlog::info("Initializing SoapySDR");
|
spdlog::info("Initializing SoapySDR");
|
||||||
soapy.init();
|
soapy.init();
|
||||||
|
|
||||||
|
gui::menu.registerEntry("Source", sourceMenu, NULL);
|
||||||
|
|
||||||
gui::freqSelect.init();
|
gui::freqSelect.init();
|
||||||
|
|
||||||
fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
|
||||||
@ -168,16 +279,17 @@ void windowInit() {
|
|||||||
|
|
||||||
spdlog::info("Loading modules");
|
spdlog::info("Loading modules");
|
||||||
mod::initAPI(&gui::waterfall);
|
mod::initAPI(&gui::waterfall);
|
||||||
mod::loadFromList(config::getRootDirectory() + "/module_list.json");
|
mod::loadFromList(ROOT_DIR "/module_list.json");
|
||||||
|
|
||||||
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF((config::getRootDirectory() + "/res/fonts/Roboto-Medium.ttf").c_str(), 128.0f);
|
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(ROOT_DIR "/res/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
|
||||||
|
|
||||||
// Load last source configuration
|
// Load last source configuration
|
||||||
uint64_t frequency = config::config["frequency"];
|
core::configManager.aquire();
|
||||||
sourceName = config::config["source"];
|
uint64_t frequency = core::configManager.conf["frequency"];
|
||||||
|
sourceName = core::configManager.conf["source"];
|
||||||
auto _sourceIt = std::find(soapy.devNameList.begin(), soapy.devNameList.end(), sourceName);
|
auto _sourceIt = std::find(soapy.devNameList.begin(), soapy.devNameList.end(), sourceName);
|
||||||
if (_sourceIt != soapy.devNameList.end() && config::config["sourceSettings"].contains(sourceName)) {
|
if (_sourceIt != soapy.devNameList.end() && core::configManager.conf["sourceSettings"].contains(sourceName)) {
|
||||||
json sourceSettings = config::config["sourceSettings"][sourceName];
|
json sourceSettings = core::configManager.conf["sourceSettings"][sourceName];
|
||||||
devId = std::distance(soapy.devNameList.begin(), _sourceIt);
|
devId = std::distance(soapy.devNameList.begin(), _sourceIt);
|
||||||
soapy.setDevice(soapy.devList[devId]);
|
soapy.setDevice(soapy.devList[devId]);
|
||||||
loadSourceConfig(sourceName);
|
loadSourceConfig(sourceName);
|
||||||
@ -186,7 +298,7 @@ void windowInit() {
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
bool settingsFound = false;
|
bool settingsFound = false;
|
||||||
for (std::string devName : soapy.devNameList) {
|
for (std::string devName : soapy.devNameList) {
|
||||||
if (config::config["sourceSettings"].contains(devName)) {
|
if (core::configManager.conf["sourceSettings"].contains(devName)) {
|
||||||
sourceName = devName;
|
sourceName = devName;
|
||||||
settingsFound = true;
|
settingsFound = true;
|
||||||
devId = i;
|
devId = i;
|
||||||
@ -222,17 +334,17 @@ void windowInit() {
|
|||||||
// Switch to double for all frequecies and bandwidth
|
// Switch to double for all frequecies and bandwidth
|
||||||
|
|
||||||
// Update UI settings
|
// Update UI settings
|
||||||
fftMin = config::config["min"];
|
fftMin = core::configManager.conf["min"];
|
||||||
fftMax = config::config["max"];
|
fftMax = core::configManager.conf["max"];
|
||||||
gui::waterfall.setFFTMin(fftMin);
|
gui::waterfall.setFFTMin(fftMin);
|
||||||
gui::waterfall.setWaterfallMin(fftMin);
|
gui::waterfall.setWaterfallMin(fftMin);
|
||||||
gui::waterfall.setFFTMax(fftMax);
|
gui::waterfall.setFFTMax(fftMax);
|
||||||
gui::waterfall.setWaterfallMax(fftMax);
|
gui::waterfall.setWaterfallMax(fftMax);
|
||||||
|
|
||||||
bandPlanEnabled.val = config::config["bandPlanEnabled"];
|
bandPlanEnabled.val = core::configManager.conf["bandPlanEnabled"];
|
||||||
bandPlanEnabled.markAsChanged();
|
bandPlanEnabled.markAsChanged();
|
||||||
|
|
||||||
std::string bandPlanName = config::config["bandPlan"];
|
std::string bandPlanName = core::configManager.conf["bandPlan"];
|
||||||
auto _bandplanIt = bandplan::bandplans.find(bandPlanName);
|
auto _bandplanIt = bandplan::bandplans.find(bandPlanName);
|
||||||
if (_bandplanIt != bandplan::bandplans.end()) {
|
if (_bandplanIt != bandplan::bandplans.end()) {
|
||||||
bandplanId.val = std::distance(bandplan::bandplans.begin(), bandplan::bandplans.find(bandPlanName));
|
bandplanId.val = std::distance(bandplan::bandplans.begin(), bandplan::bandplans.find(bandPlanName));
|
||||||
@ -262,7 +374,7 @@ void windowInit() {
|
|||||||
gui::waterfall.selectFirstVFO();
|
gui::waterfall.selectFirstVFO();
|
||||||
|
|
||||||
for (auto [name, stream] : audio::streams) {
|
for (auto [name, stream] : audio::streams) {
|
||||||
if (config::config["audio"].contains(name)) {
|
if (core::configManager.conf["audio"].contains(name)) {
|
||||||
bool running = audio::streams[name]->running;
|
bool running = audio::streams[name]->running;
|
||||||
audio::stopStream(name);
|
audio::stopStream(name);
|
||||||
loadAudioConfig(name);
|
loadAudioConfig(name);
|
||||||
@ -277,16 +389,18 @@ void windowInit() {
|
|||||||
volume = &audio::streams[audioStreamName]->volume;
|
volume = &audio::streams[audioStreamName]->volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
menuWidth = config::config["menuWidth"];
|
menuWidth = core::configManager.conf["menuWidth"];
|
||||||
newWidth = menuWidth;
|
newWidth = menuWidth;
|
||||||
|
|
||||||
showWaterfall = config::config["showWaterfall"];
|
showWaterfall = core::configManager.conf["showWaterfall"];
|
||||||
if (!showWaterfall) {
|
if (!showWaterfall) {
|
||||||
gui::waterfall.hideWaterfall();
|
gui::waterfall.hideWaterfall();
|
||||||
}
|
}
|
||||||
|
|
||||||
fftHeight = config::config["fftHeight"];
|
fftHeight = core::configManager.conf["fftHeight"];
|
||||||
gui::waterfall.setFFTHeight(fftHeight);
|
gui::waterfall.setFFTHeight(fftHeight);
|
||||||
|
|
||||||
|
core::configManager.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVFO(float freq) {
|
void setVFO(float freq) {
|
||||||
@ -382,8 +496,9 @@ void drawWindow() {
|
|||||||
if (vfo->centerOffsetChanged) {
|
if (vfo->centerOffsetChanged) {
|
||||||
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
|
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
|
||||||
gui::freqSelect.frequencyChanged = false;
|
gui::freqSelect.frequencyChanged = false;
|
||||||
config::config["frequency"] = gui::freqSelect.frequency;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
sigpath::vfoManager.updateFromWaterfall(&gui::waterfall);
|
sigpath::vfoManager.updateFromWaterfall(&gui::waterfall);
|
||||||
@ -397,8 +512,9 @@ void drawWindow() {
|
|||||||
if (audioStreamName != "") {
|
if (audioStreamName != "") {
|
||||||
volume = &audio::streams[audioStreamName]->volume;
|
volume = &audio::streams[audioStreamName]->volume;
|
||||||
}
|
}
|
||||||
config::config["frequency"] = gui::freqSelect.frequency;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gui::freqSelect.frequencyChanged) {
|
if (gui::freqSelect.frequencyChanged) {
|
||||||
@ -407,16 +523,18 @@ void drawWindow() {
|
|||||||
vfo->centerOffsetChanged = false;
|
vfo->centerOffsetChanged = false;
|
||||||
vfo->lowerOffsetChanged = false;
|
vfo->lowerOffsetChanged = false;
|
||||||
vfo->upperOffsetChanged = false;
|
vfo->upperOffsetChanged = false;
|
||||||
config::config["frequency"] = gui::freqSelect.frequency;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gui::waterfall.centerFreqMoved) {
|
if (gui::waterfall.centerFreqMoved) {
|
||||||
gui::waterfall.centerFreqMoved = false;
|
gui::waterfall.centerFreqMoved = false;
|
||||||
soapy.setFrequency(gui::waterfall.getCenterFrequency());
|
soapy.setFrequency(gui::waterfall.getCenterFrequency());
|
||||||
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
|
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
|
||||||
config::config["frequency"] = gui::freqSelect.frequency;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dcbias.changed()) {
|
if (dcbias.changed()) {
|
||||||
@ -434,8 +552,9 @@ void drawWindow() {
|
|||||||
int _fftHeight = gui::waterfall.getFFTHeight();
|
int _fftHeight = gui::waterfall.getFFTHeight();
|
||||||
if (fftHeight != _fftHeight) {
|
if (fftHeight != _fftHeight) {
|
||||||
fftHeight = _fftHeight;
|
fftHeight = _fftHeight;
|
||||||
config::config["fftHeight"] = fftHeight;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["fftHeight"] = fftHeight;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 vMin = ImGui::GetWindowContentRegionMin();
|
ImVec2 vMin = ImGui::GetWindowContentRegionMin();
|
||||||
@ -478,12 +597,13 @@ void drawWindow() {
|
|||||||
ImGui::SetNextItemWidth(200);
|
ImGui::SetNextItemWidth(200);
|
||||||
if (ImGui::SliderFloat("##_2_", volume, 0.0f, 1.0f, "")) {
|
if (ImGui::SliderFloat("##_2_", volume, 0.0f, 1.0f, "")) {
|
||||||
if (audioStreamName != "") {
|
if (audioStreamName != "") {
|
||||||
if (!config::config["audio"].contains(audioStreamName)) {
|
core::configManager.aquire();
|
||||||
|
if (!core::configManager.conf["audio"].contains(audioStreamName)) {
|
||||||
saveAudioConfig(audioStreamName);
|
saveAudioConfig(audioStreamName);
|
||||||
}
|
}
|
||||||
audio::streams[audioStreamName]->audio->setVolume(*volume);
|
audio::streams[audioStreamName]->audio->setVolume(*volume);
|
||||||
config::config["audio"][audioStreamName]["volume"] = *volume;
|
core::configManager.conf["audio"][audioStreamName]["volume"] = *volume;
|
||||||
config::configModified = true;
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,8 +649,9 @@ void drawWindow() {
|
|||||||
if(!down && grabbingMenu) {
|
if(!down && grabbingMenu) {
|
||||||
grabbingMenu = false;
|
grabbingMenu = false;
|
||||||
menuWidth = newWidth;
|
menuWidth = newWidth;
|
||||||
config::config["menuWidth"] = menuWidth;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["menuWidth"] = menuWidth;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left Column
|
// Left Column
|
||||||
@ -543,104 +664,7 @@ void drawWindow() {
|
|||||||
ImGui::BeginChild("Left Column");
|
ImGui::BeginChild("Left Column");
|
||||||
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
|
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
|
||||||
|
|
||||||
if (ImGui::CollapsingHeader("Source", ImGuiTreeNodeFlags_DefaultOpen)) {
|
gui::menu.draw();
|
||||||
if (playing) { style::beginDisabled(); };
|
|
||||||
|
|
||||||
ImGui::PushItemWidth(menuColumnWidth);
|
|
||||||
if (ImGui::Combo("##_0_", &devId, soapy.txtDevList.c_str())) {
|
|
||||||
spdlog::info("Changed input device: {0}", devId);
|
|
||||||
sourceName = soapy.devNameList[devId];
|
|
||||||
soapy.setDevice(soapy.devList[devId]);
|
|
||||||
|
|
||||||
if (config::config["sourceSettings"].contains(sourceName)) {
|
|
||||||
loadSourceConfig(sourceName);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
srId = 0;
|
|
||||||
sampleRate = soapy.getSampleRate();
|
|
||||||
bw.val = sampleRate;
|
|
||||||
gui::waterfall.setBandwidth(sampleRate);
|
|
||||||
gui::waterfall.setViewBandwidth(sampleRate);
|
|
||||||
sigpath::signalPath.setSampleRate(sampleRate);
|
|
||||||
|
|
||||||
if (soapy.gainList.size() >= 0) {
|
|
||||||
delete[] uiGains;
|
|
||||||
uiGains = new float[soapy.gainList.size()];
|
|
||||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
|
||||||
uiGains[i] = soapy.currentGains[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setVFO(gui::freqSelect.frequency);
|
|
||||||
config::config["source"] = sourceName;
|
|
||||||
config::configModified = true;
|
|
||||||
}
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
if (ImGui::Combo("##_1_", &srId, soapy.txtSampleRateList.c_str())) {
|
|
||||||
spdlog::info("Changed sample rate: {0}", srId);
|
|
||||||
sampleRate = soapy.sampleRates[srId];
|
|
||||||
soapy.setSampleRate(sampleRate);
|
|
||||||
gui::waterfall.setBandwidth(sampleRate);
|
|
||||||
gui::waterfall.setViewBandwidth(sampleRate);
|
|
||||||
sigpath::signalPath.setSampleRate(sampleRate);
|
|
||||||
bw.val = sampleRate;
|
|
||||||
|
|
||||||
if (!config::config["sourceSettings"].contains(sourceName)) {
|
|
||||||
saveCurrentSource();
|
|
||||||
}
|
|
||||||
config::config["sourceSettings"][sourceName]["sampleRate"] = sampleRate;
|
|
||||||
config::configModified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
bool noDevice = (soapy.devList.size() == 0);
|
|
||||||
if (ImGui::Button("Refresh", ImVec2(menuColumnWidth - ImGui::GetCursorPosX(), 0.0f))) {
|
|
||||||
soapy.refresh();
|
|
||||||
if (noDevice && soapy.devList.size() > 0) {
|
|
||||||
sourceName = soapy.devNameList[0];
|
|
||||||
soapy.setDevice(soapy.devList[0]);
|
|
||||||
if (config::config["sourceSettings"][sourceName]) {
|
|
||||||
loadSourceConfig(sourceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playing) { style::endDisabled(); };
|
|
||||||
|
|
||||||
float maxTextLength = 0;
|
|
||||||
float txtLen = 0;
|
|
||||||
char buf[100];
|
|
||||||
|
|
||||||
// Calculate the spacing
|
|
||||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
|
||||||
sprintf(buf, "%s gain", soapy.gainList[i].c_str());
|
|
||||||
txtLen = ImGui::CalcTextSize(buf).x;
|
|
||||||
if (txtLen > maxTextLength) {
|
|
||||||
maxTextLength = txtLen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < soapy.gainList.size(); i++) {
|
|
||||||
ImGui::Text("%s gain", soapy.gainList[i].c_str());
|
|
||||||
ImGui::SameLine();
|
|
||||||
sprintf(buf, "##_gain_slide_%d_", i);
|
|
||||||
|
|
||||||
ImGui::SetCursorPosX(maxTextLength + 5);
|
|
||||||
ImGui::PushItemWidth(menuColumnWidth - (maxTextLength + 5));
|
|
||||||
if (ImGui::SliderFloat(buf, &uiGains[i], soapy.gainRanges[i].minimum(), soapy.gainRanges[i].maximum())) {
|
|
||||||
soapy.setGain(i, uiGains[i]);
|
|
||||||
if (!config::config["sourceSettings"].contains(sourceName)) {
|
|
||||||
saveCurrentSource();
|
|
||||||
}
|
|
||||||
config::config["sourceSettings"][sourceName]["gains"][soapy.gainList[i]] = uiGains[i];
|
|
||||||
config::configModified = true;
|
|
||||||
}
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < modCount; i++) {
|
for (int i = 0; i < modCount; i++) {
|
||||||
if (ImGui::CollapsingHeader(mod::moduleNames[i].c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
|
if (ImGui::CollapsingHeader(mod::moduleNames[i].c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
@ -673,12 +697,13 @@ void drawWindow() {
|
|||||||
stream->sampleRateId = 0;
|
stream->sampleRateId = 0;
|
||||||
|
|
||||||
// Create config if it doesn't exist
|
// Create config if it doesn't exist
|
||||||
if (!config::config["audio"].contains(name)) {
|
core::configManager.aquire();
|
||||||
|
if (!core::configManager.conf["audio"].contains(name)) {
|
||||||
saveAudioConfig(name);
|
saveAudioConfig(name);
|
||||||
}
|
}
|
||||||
config::config["audio"][name]["device"] = stream->audio->deviceNames[stream->deviceId];
|
core::configManager.conf["audio"][name]["device"] = stream->audio->deviceNames[stream->deviceId];
|
||||||
config::config["audio"][name]["sampleRate"] = stream->audio->devices[stream->deviceId].sampleRates[0];
|
core::configManager.conf["audio"][name]["sampleRate"] = stream->audio->devices[stream->deviceId].sampleRates[0];
|
||||||
config::configModified = true;
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
if (ImGui::Combo(("##_audio_sr_0_" + name).c_str(), &stream->sampleRateId, stream->audio->devices[deviceId].txtSampleRates.c_str())) {
|
if (ImGui::Combo(("##_audio_sr_0_" + name).c_str(), &stream->sampleRateId, stream->audio->devices[deviceId].txtSampleRates.c_str())) {
|
||||||
audio::stopStream(name);
|
audio::stopStream(name);
|
||||||
@ -688,21 +713,23 @@ void drawWindow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create config if it doesn't exist
|
// Create config if it doesn't exist
|
||||||
if (!config::config["audio"].contains(name)) {
|
core::configManager.aquire();
|
||||||
|
if (!core::configManager.conf["audio"].contains(name)) {
|
||||||
saveAudioConfig(name);
|
saveAudioConfig(name);
|
||||||
}
|
}
|
||||||
config::config["audio"][name]["sampleRate"] = stream->audio->devices[deviceId].sampleRates[stream->sampleRateId];
|
core::configManager.conf["audio"][name]["sampleRate"] = stream->audio->devices[deviceId].sampleRates[stream->sampleRateId];
|
||||||
config::configModified = true;
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
if (ImGui::SliderFloat(("##_audio_vol_0_" + name).c_str(), &stream->volume, 0.0f, 1.0f, "")) {
|
if (ImGui::SliderFloat(("##_audio_vol_0_" + name).c_str(), &stream->volume, 0.0f, 1.0f, "")) {
|
||||||
stream->audio->setVolume(stream->volume);
|
stream->audio->setVolume(stream->volume);
|
||||||
|
|
||||||
// Create config if it doesn't exist
|
// Create config if it doesn't exist
|
||||||
if (!config::config["audio"].contains(name)) {
|
core::configManager.aquire();
|
||||||
|
if (!core::configManager.conf["audio"].contains(name)) {
|
||||||
saveAudioConfig(name);
|
saveAudioConfig(name);
|
||||||
}
|
}
|
||||||
config::config["audio"][name]["volume"] = stream->volume;
|
core::configManager.conf["audio"][name]["volume"] = stream->volume;
|
||||||
config::configModified = true;
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
count++;
|
count++;
|
||||||
@ -718,13 +745,15 @@ void drawWindow() {
|
|||||||
if (ImGui::CollapsingHeader("Band Plan", ImGuiTreeNodeFlags_DefaultOpen)) {
|
if (ImGui::CollapsingHeader("Band Plan", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
ImGui::PushItemWidth(menuColumnWidth);
|
ImGui::PushItemWidth(menuColumnWidth);
|
||||||
if (ImGui::Combo("##_4_", &bandplanId.val, bandplan::bandplanNameTxt.c_str())) {
|
if (ImGui::Combo("##_4_", &bandplanId.val, bandplan::bandplanNameTxt.c_str())) {
|
||||||
config::config["bandPlan"] = bandplan::bandplanNames[bandplanId.val];
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["bandPlan"] = bandplan::bandplanNames[bandplanId.val];
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
ImGui::PopItemWidth();
|
ImGui::PopItemWidth();
|
||||||
if (ImGui::Checkbox("Enabled", &bandPlanEnabled.val)) {
|
if (ImGui::Checkbox("Enabled", &bandPlanEnabled.val)) {
|
||||||
config::config["bandPlanEnabled"] = bandPlanEnabled.val;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["bandPlanEnabled"] = bandPlanEnabled.val;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
bandplan::BandPlan_t plan = bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]];
|
bandplan::BandPlan_t plan = bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]];
|
||||||
ImGui::Text("Country: %s (%s)", plan.countryName.c_str(), plan.countryCode.c_str());
|
ImGui::Text("Country: %s (%s)", plan.countryName.c_str(), plan.countryCode.c_str());
|
||||||
@ -784,8 +813,9 @@ void drawWindow() {
|
|||||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
||||||
if (ImGui::VSliderFloat("##_8_", ImVec2(20.0f, 150.0f), &fftMax, 0.0f, -100.0f, "")) {
|
if (ImGui::VSliderFloat("##_8_", ImVec2(20.0f, 150.0f), &fftMax, 0.0f, -100.0f, "")) {
|
||||||
fftMax = std::max<float>(fftMax, fftMin + 10);
|
fftMax = std::max<float>(fftMax, fftMin + 10);
|
||||||
config::config["max"] = fftMax;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["max"] = fftMax;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::NewLine();
|
ImGui::NewLine();
|
||||||
@ -795,8 +825,9 @@ void drawWindow() {
|
|||||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0f) - 10);
|
||||||
if (ImGui::VSliderFloat("##_9_", ImVec2(20.0f, 150.0f), &fftMin, 0.0f, -100.0f, "")) {
|
if (ImGui::VSliderFloat("##_9_", ImVec2(20.0f, 150.0f), &fftMin, 0.0f, -100.0f, "")) {
|
||||||
fftMin = std::min<float>(fftMax - 10, fftMin);
|
fftMin = std::min<float>(fftMax - 10, fftMin);
|
||||||
config::config["min"] = fftMin;
|
core::configManager.aquire();
|
||||||
config::configModified = true;
|
core::configManager.conf["min"] = fftMin;
|
||||||
|
core::configManager.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <gui/style.h>
|
#include <gui/style.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <signal_path/signal_path.h>
|
#include <signal_path/signal_path.h>
|
||||||
|
#include <core.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
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@ void Menu::registerEntry(std::string name, void (*drawHandler)(void* ctx), void*
|
|||||||
item.drawHandler = drawHandler;
|
item.drawHandler = drawHandler;
|
||||||
item.ctx = ctx;
|
item.ctx = ctx;
|
||||||
items[name] = item;
|
items[name] = item;
|
||||||
|
if (!isInOrderList(name)) {
|
||||||
|
order.push_back(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::removeEntry(std::string name) {
|
void Menu::removeEntry(std::string name) {
|
||||||
@ -18,7 +21,21 @@ void Menu::removeEntry(std::string name) {
|
|||||||
void Menu::draw() {
|
void Menu::draw() {
|
||||||
MenuItem_t item;
|
MenuItem_t item;
|
||||||
for (std::string name : order) {
|
for (std::string name : order) {
|
||||||
|
if (items.find(name) == items.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
item = items[name];
|
item = items[name];
|
||||||
|
if (ImGui::CollapsingHeader(name.c_str(), ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
item.drawHandler(item.ctx);
|
item.drawHandler(item.ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Menu::isInOrderList(std::string name) {
|
||||||
|
for (std::string _name : order) {
|
||||||
|
if (_name == name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <imgui/imgui.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -19,5 +20,7 @@ public:
|
|||||||
std::vector<std::string> order;
|
std::vector<std::string> order;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool isInOrderList(std::string name);
|
||||||
|
|
||||||
std::map<std::string, MenuItem_t> items;
|
std::map<std::string, MenuItem_t> items;
|
||||||
};
|
};
|
@ -9,7 +9,7 @@ namespace style {
|
|||||||
ImGui::GetStyle().PopupRounding = 0.0f;
|
ImGui::GetStyle().PopupRounding = 0.0f;
|
||||||
ImGui::GetStyle().ScrollbarRounding = 0.0f;
|
ImGui::GetStyle().ScrollbarRounding = 0.0f;
|
||||||
|
|
||||||
ImGui::GetIO().Fonts->AddFontFromFileTTF((config::getRootDirectory() + "/res/fonts/Roboto-Medium.ttf").c_str(), 16.0f);
|
ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(ROOT_DIR "/res/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
|
||||||
|
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
@ -27,7 +27,7 @@ namespace style {
|
|||||||
ImGui::GetStyle().PopupRounding = 0.0f;
|
ImGui::GetStyle().PopupRounding = 0.0f;
|
||||||
ImGui::GetStyle().ScrollbarRounding = 0.0f;
|
ImGui::GetStyle().ScrollbarRounding = 0.0f;
|
||||||
|
|
||||||
ImGui::GetIO().Fonts->AddFontFromFileTTF((config::getRootDirectory() + "/res/fonts/Roboto-Medium.ttf").c_str(), 16.0f);
|
ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(ROOT_DIR "/res/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
|
||||||
|
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
|
@ -2,12 +2,16 @@
|
|||||||
#include <module.h>
|
#include <module.h>
|
||||||
#include <path.h>
|
#include <path.h>
|
||||||
#include <watcher.h>
|
#include <watcher.h>
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||||
#define DEEMP_LIST "50µS\00075µS\000none\000"
|
#define DEEMP_LIST "50µS\00075µS\000none\000"
|
||||||
|
|
||||||
mod::API_t* API;
|
mod::API_t* API;
|
||||||
|
|
||||||
|
ConfigManager config;
|
||||||
|
bool firstInit = true;
|
||||||
|
|
||||||
struct RadioContext_t {
|
struct RadioContext_t {
|
||||||
std::string name;
|
std::string name;
|
||||||
int demod = 1;
|
int demod = 1;
|
||||||
@ -21,12 +25,16 @@ struct RadioContext_t {
|
|||||||
MOD_EXPORT void* _INIT_(mod::API_t* _API, ImGuiContext* imctx, std::string _name) {
|
MOD_EXPORT void* _INIT_(mod::API_t* _API, ImGuiContext* imctx, std::string _name) {
|
||||||
API = _API;
|
API = _API;
|
||||||
RadioContext_t* ctx = new RadioContext_t;
|
RadioContext_t* ctx = new RadioContext_t;
|
||||||
|
|
||||||
ctx->name = _name;
|
ctx->name = _name;
|
||||||
|
|
||||||
|
ctx->demod = 1;
|
||||||
ctx->bandWidth = 200000;
|
ctx->bandWidth = 200000;
|
||||||
ctx->bandWidthMin = 100000;
|
ctx->bandWidthMin = 100000;
|
||||||
ctx->bandWidthMax = 200000;
|
ctx->bandWidthMax = 200000;
|
||||||
ctx->sigPath.init(_name, 200000, 1000);
|
ctx->sigPath.init(_name, 200000, 1000);
|
||||||
ctx->sigPath.start();
|
ctx->sigPath.start();
|
||||||
|
ctx->sigPath.setDemodulator(SigPath::DEMOD_FM, ctx->bandWidth);
|
||||||
ImGui::SetCurrentContext(imctx);
|
ImGui::SetCurrentContext(imctx);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
"device": "Speakers (Realtek High Definiti",
|
"device": "Speakers (Realtek High Definiti",
|
||||||
"sampleRate": 48000.0,
|
"sampleRate": 48000.0,
|
||||||
"volume": 0.602150559425354
|
"volume": 0.602150559425354
|
||||||
|
},
|
||||||
|
"Radio 1": {
|
||||||
|
"device": "Speakers (Realtek High Definiti",
|
||||||
|
"sampleRate": 48000.0,
|
||||||
|
"volume": 0.6881720423698425
|
||||||
|
},
|
||||||
|
"Radio 2": {
|
||||||
|
"device": "Speakers (Realtek High Definiti",
|
||||||
|
"sampleRate": 48000.0,
|
||||||
|
"volume": 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bandPlan": "General",
|
"bandPlan": "General",
|
||||||
@ -19,7 +29,7 @@
|
|||||||
"sourceSettings": {
|
"sourceSettings": {
|
||||||
"Generic RTL2832U OEM :: 00000001": {
|
"Generic RTL2832U OEM :: 00000001": {
|
||||||
"gains": {
|
"gains": {
|
||||||
"TUNER": 0.0
|
"TUNER": 11.625
|
||||||
},
|
},
|
||||||
"sampleRate": 2560000
|
"sampleRate": 2560000
|
||||||
},
|
},
|
||||||
@ -36,7 +46,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"windowSize": {
|
"windowSize": {
|
||||||
"h": 720,
|
"h": 784,
|
||||||
"w": 1280
|
"w": 1460
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"Radio": "./radio/Release/radio.dll",
|
"Radio 1": "./radio/Release/radio.dll",
|
||||||
"Recorder": "./recorder/Release/recorder.dll"
|
"Recorder 1": "./recorder/Release/recorder.dll"
|
||||||
}
|
}
|
||||||
|
5
root_dev/radio_config.json
Normal file
5
root_dev/radio_config.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"Radio 1": {
|
||||||
|
"demodulator":1
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user