# `SpectrumAnalyzer` — magnitude spectrum + scalar features ## Purpose `SpectrumAnalyzer` is the workhorse analysis op of this package: it slices an `AudioDocument` into overlapping frames, windows each frame, runs the real FFT, and reduces the per-bin magnitudes into a fixed-length `spectrum` plus three scalar features — centroid, rolloff, flux. The default 128-bin output is the standard size used by visualisers and feature pipelines. The class implements `analyze` (single-shot whole document), `analyzeStream` (per-frame async generator suitable for real-time visualisation), and `analyzeBlock` (one already-windowed block via a `BlockContext`). ## Features - Slices `doc` into `frameSize`/`hopSize` overlapping frames (defaults `2048`/`512`). - Hann window by default; Hamming or Blackman selectable via `window`. - Log-spaced bucket-mean reduction to the configured `bins` (default `128`). - Centroid, 85% rolloff, and positive-flux scalars per result. - `analyzeStream` yields per-frame results; the final frame's vectors match `analyze`. - `analyzeBlock` runs a single FFT-sized block with `BlockContext.sampleRate`. ## Usage: Basic ```ts import { SpectrumAnalyzer } from "@suaveplan/audio-analysis-spectrum/analyzer/spectrum-analyzer"; const analyzer = new SpectrumAnalyzer(); const result = await analyzer.analyze(doc); console.log(result.centroid, result.rolloff, result.flux, result.spectrum); ``` ## Usage: Advanced ```ts const analyzer = new SpectrumAnalyzer(); const ctrl = new AbortController(); setTimeout(() => ctrl.abort(), 50); try { for await (const frame of analyzer.analyzeStream(doc, { frameSize: 4096, hopSize: 1024, bins: 256, window: "blackman", signal: ctrl.signal, })) { updateVisualiser(frame.spectrum); } } catch (err) { // AUDIO_ANALYSIS_SPECTRUM.ABORTED expected on early cancel. } const block = analyzer.analyzeBlock([new Float32Array(2048)], { sampleRate: 48_000, startSample: 0, }); ``` ## API Reference - `name`, `description`, `analyze(doc, opts?)`, `analyzeStream(doc, opts?)`, `analyzeBlock(block, ctx)`. - `opts` includes `bins`, `frameSize`, `hopSize`, `window`, `signal`; defaults from the Zod schema. - Result extends `AnalysisResult` with `op: "spectrum-analyzer"`, `spectrum`, `centroid`, `rolloff`, `flux`. ## Implementation Notes The DSP pipeline lives in the `dsp` module so `SpectrumAnalyzer` stays an orchestrator. `analyze` retains only the final frame's `spectrum`/`magnitude` and the previous frame's `magnitude` so flux is well-defined. Each frame revalidates the abort signal between iterations, satisfying the mid-scan abort scenario. `analyzeBlock` does not consult an `AbortSignal` — block calls are bounded-time and the call site owns its own cancellation.