Commit Graph

1 Commits

Author SHA1 Message Date
mikkeli e8da88b6c1 Run the web UI entirely in the browser
The FastAPI backend kept one analysis session shared by every visitor and
spooled each upload to the server's /tmp, and the browser copied audio into
persistent OPFS storage. None of that fits a tool for unreleased masters, so
the web UI is now a static site that decodes and analyses in the tab:

- web/decode.js: WAV/AIFF PCM and float read directly with libsndfile's
  scaling (bit-identical to librosa.load; Chromium's WAV decoder scales
  positive int16 by 1/32767), other formats via decodeAudioData on an
  OfflineAudioContext at the header-sniffed native rate. ID3 song names.
- web/dsp.js: ports of every Metric.compute with the same numerics
  (pyloudnorm K-weighting via lfilter's DF2T recurrence, BS.1770 gating,
  EBU LRA, resample_poly's Kaiser filter for true peak, librosa.stft and
  amplitude_to_db), streaming passes with no signal-length intermediates.
- web/metrics.js: build_spec ports producing the existing plot payload.
- web/analysis-worker.js + app.js: per-tab track list and result cache, a
  worker job queue where the visible metric jumps background prefetch, and
  the renderer, which now also draws the metrics' own reference lines.

Deployment is nginx-unprivileged serving web/ read-only with
Content-Security-Policy connect-src 'none', so the page cannot make network
requests at all, and no access log. No secure context is needed, so plain
http on a LAN works. The Python web backend, its smoke test, the web extra
and the OPFS store are removed; the desktop app is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015UXA39Sh9coAx4FhRkd8R2
2026-09-14 10:16:52 +09:00