From 4dc0df74cf9479290a9c92bf44b4e643a494c5b2 Mon Sep 17 00:00:00 2001 From: Ryzerth Date: Sun, 4 Jul 2021 02:25:36 +0200 Subject: [PATCH] Added option to show current list on FFT --- core/src/gui/main_window.cpp | 2 +- core/src/gui/menus/vfo_color.cpp | 2 +- core/src/gui/widgets/waterfall.cpp | 12 ++++++++-- core/src/gui/widgets/waterfall.h | 13 +++++++++++ core/src/signal_path/sink.cpp | 4 ++-- core/src/signal_path/sink.h | 4 ++-- core/src/utils/event.h | 10 ++++---- frequency_manager/src/main.cpp | 37 ++++++++++++++++++++++++++++++ radio/src/main.cpp | 2 +- 9 files changed, 72 insertions(+), 14 deletions(-) diff --git a/core/src/gui/main_window.cpp b/core/src/gui/main_window.cpp index dda8223..a92e34b 100644 --- a/core/src/gui/main_window.cpp +++ b/core/src/gui/main_window.cpp @@ -88,7 +88,7 @@ void MainWindow::init() { vfoCreatedHandler.handler = vfoAddedHandler; vfoCreatedHandler.ctx = this; - sigpath::vfoManager.vfoCreatedEvent.bindHandler(vfoCreatedHandler); + sigpath::vfoManager.vfoCreatedEvent.bindHandler(&vfoCreatedHandler); spdlog::info("Loading modules"); diff --git a/core/src/gui/menus/vfo_color.cpp b/core/src/gui/menus/vfo_color.cpp index ab93031..58ac6a4 100644 --- a/core/src/gui/menus/vfo_color.cpp +++ b/core/src/gui/menus/vfo_color.cpp @@ -72,7 +72,7 @@ namespace vfo_color_menu { } vfoAddHndl.handler = vfoAddHandler; - sigpath::vfoManager.vfoCreatedEvent.bindHandler(vfoAddHndl); + sigpath::vfoManager.vfoCreatedEvent.bindHandler(&vfoAddHndl); core::configManager.release(modified); } diff --git a/core/src/gui/widgets/waterfall.cpp b/core/src/gui/widgets/waterfall.cpp index 7df4e18..ad36cd0 100644 --- a/core/src/gui/widgets/waterfall.cpp +++ b/core/src/gui/widgets/waterfall.cpp @@ -174,6 +174,16 @@ namespace ImGui { } } + FFTRedrawArgs args; + args.min = ImVec2(widgetPos.x + 50, widgetPos.y + 9); + args.max = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10); + args.lowFreq = lowerFreq; + args.highFreq = upperFreq; + args.freqToPixelRatio = horizScale; + args.pixelToFreqRatio = viewBandwidth / (double)dataWidth; + args.window = window; + onFFTRedraw.emit(args); + // X Axis window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10), ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10), @@ -182,8 +192,6 @@ namespace ImGui { window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9), ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9), text, 1.0); - - } void WaterFall::drawWaterfall() { diff --git a/core/src/gui/widgets/waterfall.h b/core/src/gui/widgets/waterfall.h index ba73940..dfa453d 100644 --- a/core/src/gui/widgets/waterfall.h +++ b/core/src/gui/widgets/waterfall.h @@ -5,6 +5,7 @@ #include #include #include +#include #define WATERFALL_RESOLUTION 1000000 @@ -141,6 +142,18 @@ namespace ImGui { std::string selectedVFO = ""; bool selectedVFOChanged = false; + struct FFTRedrawArgs { + ImVec2 min; + ImVec2 max; + double lowFreq; + double highFreq; + double freqToPixelRatio; + double pixelToFreqRatio; + ImGuiWindow* window; + }; + + Event onFFTRedraw; + enum { REF_LOWER, REF_CENTER, diff --git a/core/src/signal_path/sink.cpp b/core/src/signal_path/sink.cpp index 544cf7f..6dd9e8c 100644 --- a/core/src/signal_path/sink.cpp +++ b/core/src/signal_path/sink.cpp @@ -14,11 +14,11 @@ SinkManager::SinkManager() { registerSinkProvider("None", prov); } -SinkManager::Stream::Stream(dsp::stream* in, const EventHandler& srChangeHandler, float sampleRate) { +SinkManager::Stream::Stream(dsp::stream* in, EventHandler* srChangeHandler, float sampleRate) { init(in, srChangeHandler, sampleRate); } -void SinkManager::Stream::init(dsp::stream* in, const EventHandler& srChangeHandler, float sampleRate) { +void SinkManager::Stream::init(dsp::stream* in, EventHandler* srChangeHandler, float sampleRate) { _in = in; srChange.bindHandler(srChangeHandler); _sampleRate = sampleRate; diff --git a/core/src/signal_path/sink.h b/core/src/signal_path/sink.h index 774b9d5..766ed49 100644 --- a/core/src/signal_path/sink.h +++ b/core/src/signal_path/sink.h @@ -25,9 +25,9 @@ public: class Stream { public: Stream() {} - Stream(dsp::stream* in, const EventHandler& srChangeHandler, float sampleRate); + Stream(dsp::stream* in, EventHandler* srChangeHandler, float sampleRate); - void init(dsp::stream* in, const EventHandler& srChangeHandler, float sampleRate); + void init(dsp::stream* in, EventHandler* srChangeHandler, float sampleRate); void start(); void stop(); diff --git a/core/src/utils/event.h b/core/src/utils/event.h index d44c441..8c12c87 100644 --- a/core/src/utils/event.h +++ b/core/src/utils/event.h @@ -22,16 +22,16 @@ public: void emit(T value) { for (auto const& handler : handlers) { - handler.handler(value, handler.ctx); + handler->handler(value, handler->ctx); } } - void bindHandler(const EventHandler& handler) { + void bindHandler(EventHandler* handler) { handlers.push_back(handler); } - void unbindHandler(const EventHandler& handler) { - if (handlers.find(handler) == handlers.end()) { + void unbindHandler(EventHandler* handler) { + if (std::find(handlers.begin(), handlers.end(), handler) == handlers.end()) { spdlog::error("Tried to remove a non-existant event handler"); return; } @@ -39,6 +39,6 @@ public: } private: - std::vector> handlers; + std::vector*> handlers; }; \ No newline at end of file diff --git a/frequency_manager/src/main.cpp b/frequency_manager/src/main.cpp index f6e7ecf..92d7312 100644 --- a/frequency_manager/src/main.cpp +++ b/frequency_manager/src/main.cpp @@ -55,11 +55,16 @@ public: refreshLists(); loadByName(selList); + fftRedrawHandler.ctx = this; + fftRedrawHandler.handler = fftRedraw; + gui::menu.registerEntry(name, menuHandler, this, NULL); + gui::waterfall.onFFTRedraw.bindHandler(&fftRedrawHandler); } ~FrequencyManagerModule() { gui::menu.removeEntry(name); + gui::waterfall.onFFTRedraw.unbindHandler(&fftRedrawHandler); } void enable() { @@ -461,6 +466,8 @@ private: if (selectedNames.size() == 0 && _this->selectedListName != "") { style::endDisabled(); } ImGui::EndTable(); + ImGui::Checkbox("Show on FFT", &_this->showBookmarksOnFFT); + if (_this->selectedListName == "") { style::endDisabled(); } if (_this->createOpen) { @@ -498,6 +505,32 @@ private: } } + static void fftRedraw(ImGui::WaterFall::FFTRedrawArgs args, void* ctx) { + FrequencyManagerModule* _this = (FrequencyManagerModule*)ctx; + if (!_this->showBookmarksOnFFT) { return; } + + for (auto const [_name, bm] : _this->bookmarks) { + double centerXpos = args.min.x + std::round((bm.frequency - args.lowFreq) * args.freqToPixelRatio); + + if (bm.frequency >= args.lowFreq && bm.frequency <= args.highFreq) { + args.window->DrawList->AddLine(ImVec2(centerXpos, args.min.y), ImVec2(centerXpos, args.max.y), IM_COL32(255, 255, 0, 255)); + } + + ImVec2 nameSize = ImGui::CalcTextSize(_name.c_str()); + ImVec2 rectMin = ImVec2(centerXpos-(nameSize.x/2)-5, args.min.y); + ImVec2 rectMax = ImVec2(centerXpos+(nameSize.x/2)+5, args.min.y+nameSize.y); + ImVec2 clampedRectMin = ImVec2(std::clamp(rectMin.x, args.min.x, args.max.x), rectMin.y); + ImVec2 clampedRectMax = ImVec2(std::clamp(rectMax.x, args.min.x, args.max.x), rectMax.y); + + if (clampedRectMax.x - clampedRectMin.x > 0) { + args.window->DrawList->AddRectFilled(clampedRectMin, clampedRectMax, IM_COL32(255, 255, 0, 255)); + } + if (rectMin.x >= args.min.x && rectMax.x <= args.max.x) { + args.window->DrawList->AddText(ImVec2(centerXpos-(nameSize.x/2), args.min.y), IM_COL32(0, 0, 0, 255), _name.c_str()); + } + } + } + json exportedBookmarks; bool importOpen = false; bool exportOpen = false; @@ -550,6 +583,10 @@ private: bool newListOpen = false; bool renameListOpen = false; + bool showBookmarksOnFFT = false; + + EventHandler fftRedrawHandler; + std::map bookmarks; std::string editedBookmarkName = ""; diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 7c00986..00857e8 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -56,7 +56,7 @@ public: srChangeHandler.ctx = this; srChangeHandler.handler = sampleRateChangeHandler; - stream.init(wfmDemod.getOutput(), srChangeHandler, audioSampRate); + stream.init(wfmDemod.getOutput(), &srChangeHandler, audioSampRate); sigpath::sinkManager.registerStream(name, &stream); selectDemodById(demodId);