From c51728154bf7d64a3e5228684c9d0c2884de15dc Mon Sep 17 00:00:00 2001 From: 3djc <5167938+3djc@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:50:22 +0200 Subject: [PATCH] fix(color): spectrum analyzer on non 480x272 screens (#7324) --- .../radio/radio_spectrum_analyser.cpp | 23 +++++++---- radio/src/telemetry/multi.cpp | 41 ++++--------------- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/radio/src/gui/colorlcd/radio/radio_spectrum_analyser.cpp b/radio/src/gui/colorlcd/radio/radio_spectrum_analyser.cpp index f32c7e1b0..12ffa56ed 100644 --- a/radio/src/gui/colorlcd/radio/radio_spectrum_analyser.cpp +++ b/radio/src/gui/colorlcd/radio/radio_spectrum_analyser.cpp @@ -32,6 +32,15 @@ constexpr coord_t SPECTRUM_HEIGHT = LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT - SCALE_HEIGHT - EdgeTxStyles::UI_ELEMENT_HEIGHT; +// Empirical full-scale value of bars/max/peak samples. Used to map sample +// values to chart pixels so bars fill the available height on any LCD. +constexpr uint8_t SPECTRUM_FULL_SCALE = 90; + +static inline coord_t scaleSample(uint16_t value) +{ + return (value * SPECTRUM_HEIGHT) / SPECTRUM_FULL_SCALE; +} + template coord_t getAverage(const uint8_t* value) { @@ -39,16 +48,14 @@ coord_t getAverage(const uint8_t* value) for (uint8_t i = 0; i < CNT; i++) { sum += value[i]; } - if (SPECTRUM_HEIGHT > 300) sum = sum * 2; - return sum / CNT; + return scaleSample(sum / CNT); } template <> coord_t getAverage<4>(const uint8_t* value) { uint16_t sum = value[0] + value[1] + value[2] + value[3]; - if (SPECTRUM_HEIGHT > 300) sum = sum * 2; - return sum / 4; + return scaleSample(sum / 4); } class SpectrumFooterWindow : public Window @@ -238,19 +245,17 @@ class SpectrumWindow : public Window lv_coord_t yv = SCALE_TOP - 1 - limit(0, - getAverage(&reusableBuffer.spectrumAnalyser.bars[x]) - << 1, + getAverage(&reusableBuffer.spectrumAnalyser.bars[x]), SCALE_TOP); lv_coord_t max_yv = SCALE_TOP - 1 - limit( - 0, getAverage(&reusableBuffer.spectrumAnalyser.max[x]) << 1, + 0, getAverage(&reusableBuffer.spectrumAnalyser.max[x]), SCALE_TOP); lv_coord_t peak_yv = SCALE_TOP - 1 - limit(0, - getAverage(&reusableBuffer.spectrumAnalyser.peak[x]) - << 1, + getAverage(&reusableBuffer.spectrumAnalyser.peak[x]), SCALE_TOP); maxPts[i] = {x, max_yv}; diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index 21cf69de2..e73ae8120 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -160,28 +160,14 @@ static void processMultiScannerPacket(const uint8_t *data, const uint8_t moduleI for (uint8_t channel = 0; channel <5; channel++) { uint8_t power = max(0,(data[channel+1] - 34) >> 1); // remove everything below -120dB -#if LCD_W == 480 - coord_t x = cur_channel*2; - if (x < LCD_W) { - reusableBuffer.spectrumAnalyser.bars[x] = power; - if (x + 1 < LCD_W) { - reusableBuffer.spectrumAnalyser.bars[x + 1] = power; - } - if (power > reusableBuffer.spectrumAnalyser.max[x]) { - reusableBuffer.spectrumAnalyser.max[x] = power; - if (x + 1 < LCD_W) { - reusableBuffer.spectrumAnalyser.max[x + 1] = power; - } - } - if (power > reusableBuffer.spectrumAnalyser.peak[x]) { - reusableBuffer.spectrumAnalyser.peak[x] = power; - if (x + 1 < LCD_W) { - reusableBuffer.spectrumAnalyser.peak[x + 1] = power; - } - } -#elif LCD_W == 212 - coord_t x = cur_channel; - if (x < LCD_W) { + // Spread the (MULTI_SCANNER_MAX_CHANNEL + 1) channels across the full + // chart width so the spectrum fills the screen on any LCD size. + coord_t x_start = + ((coord_t)cur_channel * LCD_W) / (MULTI_SCANNER_MAX_CHANNEL + 1); + coord_t x_end = ((coord_t)(cur_channel + 1) * LCD_W) / + (MULTI_SCANNER_MAX_CHANNEL + 1); + if (x_end <= x_start) x_end = x_start + 1; + for (coord_t x = x_start; x < x_end && x < LCD_W; x++) { reusableBuffer.spectrumAnalyser.bars[x] = power; if (power > reusableBuffer.spectrumAnalyser.max[x]) { reusableBuffer.spectrumAnalyser.max[x] = power; @@ -189,17 +175,6 @@ static void processMultiScannerPacket(const uint8_t *data, const uint8_t moduleI if (power > reusableBuffer.spectrumAnalyser.peak[x]) { reusableBuffer.spectrumAnalyser.peak[x] = power; } -#else - coord_t x = cur_channel / 2 + 1; - if (x < LCD_W) { - reusableBuffer.spectrumAnalyser.bars[x] = power; - if (power > reusableBuffer.spectrumAnalyser.max[x]) { - reusableBuffer.spectrumAnalyser.max[x] = power; - } - if (power > reusableBuffer.spectrumAnalyser.peak[x]) { - reusableBuffer.spectrumAnalyser.peak[x] = power; - } -#endif } if (++cur_channel > MULTI_SCANNER_MAX_CHANNEL) cur_channel = 0;