From 2bf7ee45c89e4184f5db187c40109a77d1097370 Mon Sep 17 00:00:00 2001 From: ericek111 Date: Wed, 25 Mar 2026 22:13:57 +0100 Subject: [PATCH] peak trace: limit min/max freq. --- src/ui/Measurements.cpp | 38 ++++++++++++++++++++++++++++++++++++-- src/ui/Measurements.h | 3 +++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/ui/Measurements.cpp b/src/ui/Measurements.cpp index 81dbc71..8890891 100644 --- a/src/ui/Measurements.cpp +++ b/src/ui/Measurements.cpp @@ -63,6 +63,7 @@ void Measurements::findPeaks(const std::vector& spectrumDB, int maxN, void Measurements::update(const std::vector& spectrumDB, double sampleRate, bool isIQ, int fftSize) { + lastSampleRate_ = sampleRate; // Always track global peak (for the readout label). if (!spectrumDB.empty()) { auto it = std::max_element(spectrumDB.begin(), spectrumDB.end()); @@ -71,12 +72,30 @@ void Measurements::update(const std::vector& spectrumDB, globalPeak_.dB = *it; globalPeak_.freq = binToFreq(bin, sampleRate, isIQ, fftSize); - // Push into peak history circular buffer + // Push into peak history circular buffer (with optional freq range filter) constexpr int kMaxHistory = 4096; if (static_cast(peakHistBins_.size()) < kMaxHistory) peakHistBins_.resize(kMaxHistory, -1); + + // Find peak within the trace frequency range + int traceBin = bin; + int bins = static_cast(spectrumDB.size()); + if (traceMinFreq > 0.0f || traceMaxFreq > 0.0f) { + double fMin = isIQ ? -sampleRate / 2.0 : 0.0; + double fMax = isIQ ? sampleRate / 2.0 : sampleRate / 2.0; + int loB = 0, hiB = bins - 1; + if (traceMinFreq > 0.0f) + loB = std::max(0, static_cast((traceMinFreq - fMin) / (fMax - fMin) * bins)); + if (traceMaxFreq > 0.0f) + hiB = std::min(bins - 1, static_cast((traceMaxFreq - fMin) / (fMax - fMin) * bins)); + if (loB <= hiB) { + auto rangeIt = std::max_element(spectrumDB.begin() + loB, spectrumDB.begin() + hiB + 1); + traceBin = static_cast(std::distance(spectrumDB.begin(), rangeIt)); + } + } + peakHistIdx_ = (peakHistIdx_ + 1) % kMaxHistory; - peakHistBins_[peakHistIdx_] = bin; + peakHistBins_[peakHistIdx_] = traceBin; if (peakHistLen_ < kMaxHistory) ++peakHistLen_; } @@ -222,6 +241,21 @@ void Measurements::drawWaterfall(const SpectrumDisplay& specDisplay, void Measurements::drawPanel() { ImGui::Checkbox("Peak trace", &showPeakTrace); + if (showPeakTrace) { + ImGui::SameLine(); + float nyquistKHz = static_cast(lastSampleRate_ / 2000.0); + float minKHz = traceMinFreq / 1000.0f; + float maxKHz = traceMaxFreq / 1000.0f; + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::DragFloatRange2("##tracerange", &minKHz, &maxKHz, 0.01f, + 0.0f, nyquistKHz, + minKHz > 0.0f ? "%.2f kHz" : "Min", + maxKHz > 0.0f ? "%.2f kHz" : "Max")) { + traceMinFreq = std::max(0.0f, minKHz * 1000.0f); + traceMaxFreq = std::max(0.0f, maxKHz * 1000.0f); + } + if (ImGui::IsItemHovered()) ImGui::SetTooltip("Peak trace frequency range (0 = no limit)"); + } if (!enabled) return; ImGui::SetNextItemWidth(-1); diff --git a/src/ui/Measurements.h b/src/ui/Measurements.h index f101a58..15c1d3a 100644 --- a/src/ui/Measurements.h +++ b/src/ui/Measurements.h @@ -46,11 +46,14 @@ public: bool showOnSpectrum = true; // draw markers on spectrum bool showOnWaterfall = false; // draw vertical lines on waterfall bool showPeakTrace = false; // draw peak history curve on waterfall + float traceMinFreq = 0.0f; // min frequency for peak trace (Hz), 0 = no limit + float traceMaxFreq = 0.0f; // max frequency for peak trace (Hz), 0 = no limit private: PeakInfo globalPeak_; // always-tracked highest peak std::vector peaks_; + double lastSampleRate_ = 48000.0; // Peak history for waterfall trace (circular buffer, newest at peakHistIdx_) std::vector peakHistBins_; // bin index per waterfall line int peakHistIdx_ = 0;