From a9c82ecc8180132edf6e9c8f7c9c25cb40747fff Mon Sep 17 00:00:00 2001 From: Ryzerth Date: Wed, 5 Aug 2020 21:13:53 +0200 Subject: [PATCH] Band plans alpha --- band_colors.json | 7 ++ bandplans/general.json | 267 +++++++++++++++++++++++++++++++++++++++++ src/bandplan.cpp | 36 ++++++ src/bandplan.h | 13 ++ src/main.cpp | 3 + src/main_window.cpp | 15 ++- src/waterfall.cpp | 62 ++++++++++ src/waterfall.h | 4 + 8 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 band_colors.json create mode 100644 bandplans/general.json diff --git a/band_colors.json b/band_colors.json new file mode 100644 index 00000000..2e9d8a95 --- /dev/null +++ b/band_colors.json @@ -0,0 +1,7 @@ +{ + "broadcast": "#0000FFFF", + "amateur": "#FF0000FF", + "aviation": "#00FF00FF", + "marine": "#00FFFFFF", + "military": "#FFFF00FF" +} \ No newline at end of file diff --git a/bandplans/general.json b/bandplans/general.json new file mode 100644 index 00000000..600c8eef --- /dev/null +++ b/bandplans/general.json @@ -0,0 +1,267 @@ +{ + "name": "General", + "country_name": "Worldwide", + "country_code": "--", + "author_name": "Ryzerth", + "author_url": "https://github.com/AlexandreRouma", + "bands": [ + { + "name": "Long Wave", + "type": "broadcast", + "start": 148500, + "end": 283500 + }, + { + "name": "Medium Wave", + "type": "broadcast", + "start": 526500, + "end": 1606500 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 2300000, + "end": 2468000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 3200000, + "end": 3400000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 3950000, + "end": 4000000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 4750000, + "end": 4995000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 5005000, + "end": 5060000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 5900000, + "end": 6200000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 7200000, + "end": 7450000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 9400000, + "end": 9900000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 11600000, + "end": 12100000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 13570000, + "end": 13870000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 15100000, + "end": 15800000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 17480000, + "end": 17900000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 18900000, + "end": 19020000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 21450000, + "end": 21850000 + }, + { + "name": "Shortwave Broadcast", + "type": "broadcast", + "start": 25670000, + "end": 26100000 + }, + { + "name": "FM Broadcast", + "type": "broadcast", + "start": 87500000, + "end": 108000000 + }, + { + "name": "Air Band VOR/ILS", + "type": "aviation", + "start": 108000000, + "end": 118000000 + }, + { + "name": "Air Band Voice", + "type": "aviation", + "start": 118000000, + "end": 137000000 + }, + { + "name": "160m Ham Band", + "type": "amateur", + "start": 1800000, + "end": 2000000 + }, + { + "name": "80m Ham Band", + "type": "amateur", + "start": 3500000, + "end": 3950000 + }, + { + "name": "60m Ham Band", + "type": "amateur", + "start": 5351500, + "end": 5366500 + }, + { + "name": "40m Ham Band", + "type": "amateur", + "start": 7000000, + "end": 7200000 + }, + { + "name": "30m Ham Band", + "type": "amateur", + "start": 10100000, + "end": 10150000 + }, + { + "name": "20m Ham Band", + "type": "amateur", + "start": 14000000, + "end": 14350000 + }, + { + "name": "17m Ham Band", + "type": "amateur", + "start": 18068000, + "end": 18168000 + }, + { + "name": "15m Ham Band", + "type": "amateur", + "start": 21000000, + "end": 21450000 + }, + { + "name": "12m Ham Band", + "type": "amateur", + "start": 24890000, + "end": 24990000 + }, + { + "name": "CB", + "type": "amateur", + "start": 26960000, + "end": 27410000 + }, + { + "name": "10m Ham Band", + "type": "amateur", + "start": 28000000, + "end": 29750000 + }, + { + "name": "6m Ham Band", + "type": "amateur", + "start": 50000000, + "end": 54000000 + }, + { + "name": "2m Ham Band", + "type": "amateur", + "start": 144000000, + "end": 148000000 + }, + { + "name": "Marine", + "type": "marine", + "start": 156000000, + "end": 162025000 + }, + { + "name": "1.25m Ham Band", + "type": "amateur", + "start": 222000000, + "end": 225000000 + }, + { + "name": "Military Air", + "type": "military", + "start": 225000000, + "end": 380000000 + }, + { + "name": "Military Sat", + "type": "military", + "start": 240000000, + "end": 270000000 + }, + { + "name": "70cm Ham Band", + "type": "amateur", + "start": 420000000, + "end": 450000000 + }, + { + "name": "PMR446", + "type": "amateur", + "start": 446000000, + "end": 446200000 + }, + { + "name": "33cm Ham Band", + "type": "amateur", + "start": 902000000, + "end": 928000000 + }, + { + "name": "23cm Ham Band", + "type": "amateur", + "start": 1240000000, + "end": 1300000000 + }, + { + "name": "13cm Ham Band", + "type": "amateur", + "start": 2300000000, + "end": 2310000000 + }, + { + "name": "13cm Ham Band", + "type": "amateur", + "start": 2390000000, + "end": 2450000000 + } + ] +} \ No newline at end of file diff --git a/src/bandplan.cpp b/src/bandplan.cpp index 55707387..47cb5591 100644 --- a/src/bandplan.cpp +++ b/src/bandplan.cpp @@ -4,6 +4,7 @@ namespace bandplan { std::map bandplans; std::vector bandplanNames; std::string bandplanNameTxt; + std::map colorTable; void generateTxt() { bandplanNameTxt = ""; @@ -49,6 +50,24 @@ namespace bandplan { j.at("bands").get_to(b.bands); } + void to_json(json& j, const BandPlanColor_t& ct) { + spdlog::error("ImGui color to JSON not implemented!!!"); + } + + void from_json(const json& j, BandPlanColor_t& ct) { + std::string col = j.get(); + if (col[0] != '#' || !std::all_of(col.begin() + 1, col.end(), ::isxdigit)) { + return; + } + uint8_t r, g, b, a; + r = std::stoi(col.substr(1, 2), NULL, 16); + g = std::stoi(col.substr(3, 2), NULL, 16); + b = std::stoi(col.substr(5, 2), NULL, 16); + a = std::stoi(col.substr(7, 2), NULL, 16); + ct.colorValue = IM_COL32(r, g, b, a); + ct.transColorValue = IM_COL32(r, g, b, 100); + } + void loadBandPlan(std::string path) { std::ifstream file(path.c_str()); json data; @@ -83,4 +102,21 @@ namespace bandplan { loadBandPlan(path); } } + + void loadColorTable(std::string path) { + if (!std::filesystem::exists(path)) { + spdlog::error("Band Plan Color Table file does not exist"); + return; + } + if (!std::filesystem::is_regular_file(path)) { + spdlog::error("Band Plan Color Table file isn't a file..."); + return; + } + std::ifstream file(path.c_str()); + json data; + data << file; + file.close(); + + colorTable = data.get>(); + } }; \ No newline at end of file diff --git a/src/bandplan.h b/src/bandplan.h index 79823073..315bc13e 100644 --- a/src/bandplan.h +++ b/src/bandplan.h @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include using nlohmann::json; @@ -28,11 +31,21 @@ namespace bandplan { void to_json(json& j, const BandPlan_t& b); void from_json(const json& j, BandPlan_t& b); + + struct BandPlanColor_t { + uint32_t colorValue; + uint32_t transColorValue; + }; + + void to_json(json& j, const BandPlanColor_t& ct); + void from_json(const json& j, BandPlanColor_t& ct); void loadBandPlan(std::string path); void loadFromDir(std::string path); + void loadColorTable(std::string path); extern std::map bandplans; extern std::vector bandplanNames; extern std::string bandplanNameTxt; + extern std::map colorTable; }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d22a72b0..dab78f88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,9 @@ int main() { spdlog::info("Loading band plans"); bandplan::loadFromDir("bandplans"); + spdlog::info("Loading band plans color table"); + bandplan::loadColorTable("band_colors.json"); + spdlog::info("Ready."); // Main loop diff --git a/src/main_window.cpp b/src/main_window.cpp index 951b15ec..1d9488f5 100644 --- a/src/main_window.cpp +++ b/src/main_window.cpp @@ -74,7 +74,7 @@ void windowInit() { watcher devId(0, true); watcher srId(0, true); -watcher bandplanId(0); +watcher bandplanId(0, true); watcher freq(90500000L); int demod = 1; watcher vfoFreq(92000000.0f); @@ -86,6 +86,7 @@ watcher bw(8000000.0f, true); int sampleRate = 1000000; bool playing = false; watcher dcbias(false, false); +watcher bandPlanEnabled(true, false); void setVFO(float freq) { float currentOff = wtf.getVFOOfset(); @@ -226,8 +227,12 @@ void drawWindow() { sigPath.setDCBiasCorrection(dcbias.val); } - if (bandplanId.changed()) { - spdlog::info("BANDPLAN CHANGED!!!!"); + if (bandplanId.changed() && bandPlanEnabled.val) { + wtf.bandplan = &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]]; + } + + if (bandPlanEnabled.changed()) { + wtf.bandplan = bandPlanEnabled.val ? &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]] : NULL; } ImVec2 vMin = ImGui::GetWindowContentRegionMin(); @@ -352,6 +357,10 @@ void drawWindow() { ImGui::PushItemWidth(ImGui::GetWindowSize().x); ImGui::Combo("##_4_", &bandplanId.val, bandplan::bandplanNameTxt.c_str()); ImGui::PopItemWidth(); + ImGui::Checkbox("Enabled", &bandPlanEnabled.val); + bandplan::BandPlan_t plan = bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]]; + ImGui::Text("Country: %s (%s)", plan.countryName, plan.countryCode); + ImGui::Text("Author: %s", plan.authorName); } ImGui::CollapsingHeader("Display"); diff --git a/src/waterfall.cpp b/src/waterfall.cpp index c7e05a15..1500a49d 100644 --- a/src/waterfall.cpp +++ b/src/waterfall.cpp @@ -289,6 +289,65 @@ namespace ImGui { waterfallUpdate = true; } + void WaterFall::drawBandPlan() { + int count = bandplan->bands.size(); + float horizScale = (float)dataWidth / viewBandwidth; + float start, end, center, aPos, bPos, cPos, width; + ImVec2 txtSz; + bool startVis, endVis; + uint32_t color, colorTrans; + for (int i = 0; i < count; i++) { + start = bandplan->bands[i].start; + end = bandplan->bands[i].end; + if (start < lowerFreq && end < lowerFreq) { + continue; + } + if (start > upperFreq && end > upperFreq) { + continue; + } + startVis = (start > lowerFreq); + endVis = (end < upperFreq); + start = std::clamp(start, lowerFreq, upperFreq); + end = std::clamp(end, lowerFreq, upperFreq); + center = (start + end) / 2.0f; + aPos = widgetPos.x + 50 + ((start - lowerFreq) * horizScale); + bPos = widgetPos.x + 50 + ((end - lowerFreq) * horizScale); + cPos = widgetPos.x + 50 + ((center - lowerFreq) * horizScale); + width = bPos - aPos; + txtSz = ImGui::CalcTextSize(bandplan->bands[i].name.c_str()); + if (bandplan::colorTable.find(bandplan->bands[i].type.c_str()) != bandplan::colorTable.end()) { + color = bandplan::colorTable[bandplan->bands[i].type].colorValue; + colorTrans = bandplan::colorTable[bandplan->bands[i].type].transColorValue; + } + else { + color = IM_COL32(255, 255, 255, 255); + colorTrans = IM_COL32(255, 255, 255, 100); + } + if (aPos <= widgetPos.x + 50) { + aPos = widgetPos.x + 51; + } + if (bPos <= widgetPos.x + 50) { + bPos = widgetPos.x + 51; + } + if (width >= 1.0f) { + window->DrawList->AddRectFilled(ImVec2(roundf(aPos), widgetPos.y + fftHeight - 25), + ImVec2(roundf(bPos), widgetPos.y + fftHeight + 10), colorTrans); + if (startVis) { + window->DrawList->AddLine(ImVec2(roundf(aPos), widgetPos.y + fftHeight - 26), + ImVec2(roundf(aPos), widgetPos.y + fftHeight + 9), color); + } + if (endVis) { + window->DrawList->AddLine(ImVec2(roundf(bPos), widgetPos.y + fftHeight - 26), + ImVec2(roundf(bPos), widgetPos.y + fftHeight + 9), color); + } + } + if (txtSz.x <= width) { + window->DrawList->AddText(ImVec2(cPos - (txtSz.x / 2.0f), widgetPos.y + fftHeight - 17), + IM_COL32(255, 255, 255, 255), bandplan->bands[i].name.c_str()); + } + } + } + void WaterFall::updateWaterfallTexture() { glBindTexture(GL_TEXTURE_2D, textureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -355,6 +414,9 @@ namespace ImGui { drawFFT(); drawWaterfall(); drawVFO(); + if (bandplan != NULL) { + drawBandPlan(); + } buf_mtx.unlock(); } diff --git a/src/waterfall.h b/src/waterfall.h index 974c6a6d..362125c4 100644 --- a/src/waterfall.h +++ b/src/waterfall.h @@ -5,6 +5,7 @@ #include #include #include +#include #define WATERFALL_RESOLUTION 1000000 @@ -58,6 +59,8 @@ namespace ImGui { bool centerFreqMoved = false; bool vfoFreqChanged = false; + bool bandplanEnabled = false; + bandplan::BandPlan_t* bandplan = NULL; enum { REF_LOWER, @@ -71,6 +74,7 @@ namespace ImGui { void drawWaterfall(); void drawFFT(); void drawVFO(); + void drawBandPlan(); void onPositionChange(); void onResize(); void updateWaterfallFb();