diff --git a/oscope-sphere/src/SpectrogramBuffer.cpp b/oscope-sphere/src/SpectrogramBuffer.cpp index 45186ee..82fece3 100644 --- a/oscope-sphere/src/SpectrogramBuffer.cpp +++ b/oscope-sphere/src/SpectrogramBuffer.cpp @@ -30,22 +30,21 @@ float SpectrogramBuffer::norm01(float magnitude) { void SpectrogramBuffer::pushColumn(const std::vector& magCh1, const std::vector& magCh2) { - const int col = writeIndex_; - const int half = height_ / 2; + const int col = writeIndex_; + const int half = height_ / 2; + const float denom = static_cast(std::max(1, half - 1)); // CH1 -> northern rows [half, height_): row half = equator (low freq), // row height_-1 = north pole (high freq). for (int r = half; r < height_; ++r) { - const float frac = static_cast(r - half) / - static_cast(half - 1); + const float frac = static_cast(r - half) / denom; data_[static_cast(r) * width_ + col] = norm01(logResample(magCh1, frac)); } // CH2 -> southern rows [0, half): row half-1 = equator (low freq), // row 0 = south pole (high freq). for (int r = 0; r < half; ++r) { - const float frac = static_cast(half - 1 - r) / - static_cast(half - 1); + const float frac = static_cast(half - 1 - r) / denom; data_[static_cast(r) * width_ + col] = norm01(logResample(magCh2, frac)); } diff --git a/oscope-sphere/tests/test_spectrogram.cpp b/oscope-sphere/tests/test_spectrogram.cpp index 01b9a23..9eb2edc 100644 --- a/oscope-sphere/tests/test_spectrogram.cpp +++ b/oscope-sphere/tests/test_spectrogram.cpp @@ -1,5 +1,6 @@ #include "check.h" #include "SpectrogramBuffer.h" +#include #include using oscope::SpectrogramBuffer; @@ -25,8 +26,22 @@ static void test_high_freq_maps_to_poles() { CHECK(d[0 * W + 0] > d[3 * W + 0]); // CH2: south pole > equator } +// A 2-row buffer (half == 1) must not divide by zero / emit NaN. +static void test_height_two_is_finite() { + SpectrogramBuffer buf(4, 2); + std::vector m(1024, 0.0f); + m[500] = 50.0f; + buf.pushColumn(m, m); + const std::vector& d = buf.data(); + bool allFinite = true; + for (float v : d) + if (!std::isfinite(v)) allFinite = false; + CHECK(allFinite); +} + int main() { test_write_index_wraps(); test_high_freq_maps_to_poles(); + test_height_two_is_finite(); REPORT(); }