"use client"; import { COLORS, VizFrame } from "./common"; function waveformPath(bars: number, w: number, h: number) { const mid = h / 2; return Array.from({ length: bars }, (_, i) => { const x = 4 + (i / (bars - 1)) * (w - 8); const y = mid + Math.sin(i * 0.35) * (h * 0.35) * (0.5 + 0.5 * Math.sin(i * 0.12)); return `${i === 0 ? "M" : "L"} ${x} ${y}`; }).join(" "); } function fftPath(bars: number, w: number, h: number) { const base = h - 4; return Array.from({ length: bars }, (_, i) => { const x = 4 + (i / (bars - 1)) * (w - 8); const peak1 = Math.exp(-((i - 8) ** 2) / 18) * (h - 12); const peak2 = Math.exp(-((i - 22) ** 2) / 30) * (h - 12) * 0.5; const peak3 = Math.exp(-((i - 38) ** 2) / 40) * (h - 12) * 0.25; const y = base - Math.max(peak1, peak2, peak3, 2); return `${i === 0 ? "M" : "L"} ${x} ${y}`; }).join(" "); } const VIEW_W = 300; const VIEW_H = 70; export function AudioSpectrogramViz() { const bars = 44; const melRows = 10; return (
waveform (T,) amplitude vs time
{Array.from({ length: 12 }).map((_, i) => { const x = 8 + i * ((VIEW_W - 16) / 11); const y = VIEW_H / 2 + Math.sin(i * 0.8) * 20; return ; })}

sample rate f_s · amplitude sampled at regular intervals

↓ FFT
FFT magnitude Hz

fundamental + harmonics + noise floor

↓ mel filterbank · log
log-mel (F, T) input to model
{Array.from({ length: bars * melRows }).map((_, i) => { const row = Math.floor(i / bars); const col = i % bars; const v = (Math.sin(col * 0.25 + row * 0.5) + 1) / 2; return (
); })}

STFT → mel filterbank → log scale · standard classifier input

); }