From cc115638d81f6e54fa098b6206e584652dba827d Mon Sep 17 00:00:00 2001 From: Jon Myers Date: Thu, 6 Nov 2025 16:38:00 -0800 Subject: [PATCH] fix: flip spectrogram frequency axis to match freq_bins ordering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The server data has row 0 = highest frequency, but freq_bins property calculates assuming row 0 = lowest frequency. This caused frequency cropping to select the wrong portion of the spectrum (e.g., requesting 200-400 Hz would actually return high frequencies like 2000-2400 Hz). Now flip the data immediately after loading in from_audio_id() so: - Row 0 = lowest frequency (matching freq_bins[0]) - Row -1 = highest frequency (matching freq_bins[-1]) This fixes frequency alignment between spectrograms and pitch contours in visualization contexts. Note: Visualizations using this API should remove any flipud() calls they were using to work around this issue. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- idtap/spectrogram.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/idtap/spectrogram.py b/idtap/spectrogram.py index 45a4431..94e1fab 100644 --- a/idtap/spectrogram.py +++ b/idtap/spectrogram.py @@ -111,6 +111,10 @@ def from_audio_id(cls, audio_id: str, client: Optional['SwaraClient'] = None) -> shape = tuple(metadata['shape']) # [freq_bins, time_frames] data = np.frombuffer(decompressed, dtype=np.uint8).reshape(shape) + # Flip frequency axis so row 0 = lowest frequency (matches freq_bins ordering) + # Server data has row 0 = highest frequency, but we want row 0 = lowest + data = np.flipud(data) + # Get exact audio duration from recording database time_resolution = None try: