fix the peak trace line running out of sync with the waterfall due to 793df68b

This commit is contained in:
2026-04-09 11:37:39 +02:00
parent bbdab305aa
commit d2ca7e745e
3 changed files with 50 additions and 30 deletions

View File

@@ -316,6 +316,10 @@ void Application::processAudio() {
// Push ALL new spectra to the waterfall so that the scroll rate
// is determined by the audio sample rate, not the display refresh.
int curCh = std::clamp(ui_.waterfallChannel, 0, nSpec - 1);
const auto& traceHist = audio_.getWaterfallHistory(curCh);
int traceHistSz = static_cast<int>(traceHist.size());
if (ui_.waterfallMultiCh && nSpec > 1) {
// For multi-channel: replay the last spectraThisFrame entries
// from channel 0's history to get per-step data. Other
@@ -353,16 +357,22 @@ void Application::processAudio() {
}
}
waterfall_.pushLineMulti(wfSpectra, wfInfo, ui_.minDB, ui_.maxDB);
// Push peak trace entry synchronized with each waterfall line.
int tIdx = std::max(0, traceHistSz - (histSz - si));
measurements_.pushPeakTrace(traceHist[tIdx],
settings.sampleRate, settings.isIQ, settings.fftSize);
}
} else {
int wfCh = std::clamp(ui_.waterfallChannel, 0, nSpec - 1);
const auto& hist = audio_.getWaterfallHistory(wfCh);
const auto& hist = audio_.getWaterfallHistory(curCh);
int histSz = static_cast<int>(hist.size());
int start = std::max(0, histSz - spectraThisFrame);
for (int si = start; si < histSz; ++si)
for (int si = start; si < histSz; ++si) {
waterfall_.pushLine(hist[si], ui_.minDB, ui_.maxDB);
measurements_.pushPeakTrace(hist[si],
settings.sampleRate, settings.isIQ, settings.fftSize);
}
}
int curCh = std::clamp(ui_.waterfallChannel, 0, nSpec - 1);
cursors_.update(audio_.getSpectrum(curCh),
settings.sampleRate, settings.isIQ, settings.fftSize);
measurements_.update(audio_.getSpectrum(curCh),

View File

@@ -61,24 +61,18 @@ void Measurements::findPeaks(const std::vector<float>& spectrumDB, int maxN,
}
}
void Measurements::update(const std::vector<float>& spectrumDB,
void Measurements::pushPeakTrace(const std::vector<float>& 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());
int bin = static_cast<int>(std::distance(spectrumDB.begin(), it));
globalPeak_.bin = bin;
globalPeak_.dB = *it;
globalPeak_.freq = binToFreq(bin, sampleRate, isIQ, fftSize);
if (spectrumDB.empty()) return;
// Push into peak history circular buffer (with optional freq range filter)
constexpr int kMaxHistory = 4096;
if (static_cast<int>(peakHistBins_.size()) < kMaxHistory)
peakHistBins_.resize(kMaxHistory, -1);
// Find peak within the trace frequency range
int traceBin = bin;
auto it = std::max_element(spectrumDB.begin(), spectrumDB.end());
int traceBin = static_cast<int>(std::distance(spectrumDB.begin(), it));
// Optionally restrict to a frequency range.
int bins = static_cast<int>(spectrumDB.size());
if (traceMinFreq > 0.0f || traceMaxFreq > 0.0f) {
double fMin = isIQ ? -sampleRate / 2.0 : 0.0;
@@ -97,6 +91,18 @@ void Measurements::update(const std::vector<float>& spectrumDB,
peakHistIdx_ = (peakHistIdx_ + 1) % kMaxHistory;
peakHistBins_[peakHistIdx_] = traceBin;
if (peakHistLen_ < kMaxHistory) ++peakHistLen_;
}
void Measurements::update(const std::vector<float>& 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());
int bin = static_cast<int>(std::distance(spectrumDB.begin(), it));
globalPeak_.bin = bin;
globalPeak_.dB = *it;
globalPeak_.freq = binToFreq(bin, sampleRate, isIQ, fftSize);
}
if (!enabled) { peaks_.clear(); return; }

View File

@@ -18,6 +18,10 @@ public:
void update(const std::vector<float>& spectrumDB,
double sampleRate, bool isIQ, int fftSize);
// Push a single peak trace entry for this spectrum (call once per waterfall line).
void pushPeakTrace(const std::vector<float>& spectrumDB,
double sampleRate, bool isIQ, int fftSize);
// Draw markers on the spectrum display area.
void draw(const SpectrumDisplay& specDisplay,
float posX, float posY, float sizeX, float sizeY,