feat(foundry): GUI loop panel — the Audacity-replacement picker (#6)
The Foundry's payoff surface: per separated catch, a "Find loops" button runs the finder (#5) and lays out its ranked Takes for the human to audition, prune, name, and forge into a kit — closing the url→stems→loops loop the whole tool was for. server.py: /api/loops (async job → find_takes → Takes JSON) and /api/export (runs export_take with the kept stems → Samples/<kit>/, then publish.link_kit). Stems already serve Range-capable for <audio>. ui/index.html: a Loops panel. Each Take shows score, bar-count, time window, bpm, tempo-unstable flag, and a row per stem with: a keep checkbox, role tag, a dep-free CANVAS waveform of that loop slice (decoded client-side via Web Audio, cached per stem, drawn in the role colour), a region-audition play button (loops [start,end] on the full stem via timeupdate), and the candidate score. A kit-name field (defaults to the slug) + Forge button writes the kept stems and auto-links. Verified end to end in Chromium (Playwright): Find loops → 8 Takes render, all 11 stem-slice canvases paint (role-coloured waveforms — vocals pink, other cyan, drums faint where quiet), no console errors. Caveat: first waveform per stem waits on the full-stem decode (~1s each, 4 stems ~5s); subsequent takes from a cached stem draw instantly. A future win is byte-range slice fetch instead of full-stem decode.
Showing
Please
register
or
sign in
to comment