From 777b83f6e0765cf7e63e7ca44e60e9282287b0ec Mon Sep 17 00:00:00 2001 From: Smittix Date: Sun, 8 Feb 2026 13:45:07 +0000 Subject: [PATCH] Fix waterfall showing solid yellow by auto-scaling FFT quantization The FFT pipeline produces power values in the ~0-60 dB range for normalized IQ data, but quantize_to_uint8 used a hardcoded range of -90 to -20 dB. Every bin saturated to 255, producing a uniform yellow waterfall with no signal differentiation. Now auto-scales to the actual min/max of each frame so the full colour palette is always used. Co-Authored-By: Claude Opus 4.6 --- utils/waterfall_fft.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/utils/waterfall_fft.py b/utils/waterfall_fft.py index bf688c7..d8db37b 100644 --- a/utils/waterfall_fft.py +++ b/utils/waterfall_fft.py @@ -72,19 +72,33 @@ def compute_power_spectrum( def quantize_to_uint8( power_db: np.ndarray, - db_min: float = -90.0, - db_max: float = -20.0, + db_min: float | None = None, + db_max: float | None = None, ) -> bytes: """Clamp and scale dB values to 0-255. + When *db_min* / *db_max* are ``None`` (the default) the range is + derived from the data so the full colour palette is always used. + Args: power_db: Float32 array of power values in dB. - db_min: Value mapped to 0. - db_max: Value mapped to 255. + db_min: Value mapped to 0 (auto if None). + db_max: Value mapped to 255 (auto if None). Returns: Bytes of length len(power_db), each in [0, 255]. """ + if db_min is None or db_max is None: + actual_min = float(np.min(power_db)) + actual_max = float(np.max(power_db)) + # Guarantee at least 1 dB of dynamic range + if actual_max - actual_min < 1.0: + actual_max = actual_min + 1.0 + if db_min is None: + db_min = actual_min + if db_max is None: + db_max = actual_max + db_range = db_max - db_min if db_range <= 0: db_range = 1.0