diff --git a/COMPLETED.md b/COMPLETED.md index 593d28b..a6ed56a 100644 --- a/COMPLETED.md +++ b/COMPLETED.md @@ -6,6 +6,68 @@ Newest entries at the top. Group by phase/wave header (mirroring `PLAN.md` / `CM --- +## WaveformSeeker Wave 1 — Loudness profile + layout refactor + +**Status:** W1-T1 (backend loudness computation) and W1-T3 (player layout refactor) landed on 2026-06-05. + +### W1-T1 — Backend waveform loudness profiling + +**Landed 2026-06-05.** + +Implemented Phase 1 of the WaveformSeeker feature (`product-notes/spectrum-seeker.md`): loudness-profile computation and storage for preprocessed waveform data. + +**Backend changes (`DeepDrftContent`):** +- Added `ILoudnessAlgorithm` strategy interface for swappable loudness computation. +- Implemented `RmsLoudnessAlgorithm` — first loudness algorithm using root-mean-square; future LUFS implementation swaps in via the same interface without touching service, wire format, or storage. +- `WaveformProfileService` — computes peak-normalized loudness profile from PCM WAV (one linear buffer pass), buckets by time slice, normalizes to `[0,1]`, stores as byte-quantized sidecar in new `profiles` vault (FileDatabase `MediaFileVault`). +- `WaveformProfileOptions` — config-bound options object carrying `BucketCount` (default 512) and future algorithm-selection knobs. + +**Integration changes (`DeepDrftAPI`):** +- Wired `WaveformProfileService` into `UnifiedTrackService.UploadAsync` — profile computed on upload, stored immediately, failure silently swallowed (consistent with FileDatabase philosophy in `CLAUDE.md`). + +**Models (`DeepDrftModels`):** +- `WaveformProfileDto` — carries quantized profile data; format independent of algorithm or bucket count. + +**Testing (`DeepDrftTests`):** +- 4 new unit tests: RMS algorithm correctness against known-good PCM samples, swappable-algorithm contract (two strategies swap cleanly), and integration with `WaveformProfileService`. + +**Architecture notes:** +- Profile is derived binary content; stored in FileDatabase vault sidecar per `CLAUDE.md` principle ("binary content lives in the vault"). +- Loudness measure is an abstraction (not hardwired RMS) — RMS→LUFS future change requires only a new `ILoudnessAlgorithm` implementation, no refactoring of service, component, or wire format. +- No external audio-processing dependency pulled in for RMS — reuses existing PCM parser from `AudioProcessor`. +- Cost: one linear pass over PCM buffer at upload (few hundred ms for typical WAV); never on playback path. + +### W1-T3 — Player layout refactor (SpectrumVisualizer relocation + VolumeZone rename) + +**Landed 2026-06-05.** + +Implemented Phase 3 of the WaveformSeeker feature: architectural layout move separating live-spectrum visualization from loudness-over-time seeking. + +**Conceptual split:** +- Live-spectrum (FFT frequency bars, `SpectrumVisualizer`) moved from `PlayerSeekZone` → stacked above the volume slider in new `VolumeZone`. Conceptually with the output level. +- Static loudness-over-time (future `WaveformSeeker`) takes over the seek zone. Conceptually with transport position. + +**Component changes (`DeepDrftPublic.Client/Controls/AudioPlayerBar`):** +- `VolumeControls.razor` → renamed **`VolumeZone.razor`** for symmetry with transport and seek zones; now a vertical stack hosting `SpectrumVisualizer` above the volume slider. +- `SpectrumVisualizer` — `BucketCount` parameter defaulted to 24 buckets (down from 32) to fit the narrow volume cluster; set `flex-shrink: 0` to pin the spectrum to a fixed footprint above the volume control. +- `PlayerSeekZone.razor` — `SpectrumVisualizer` block removed; placeholder for future `WaveformSeeker` component. + +**CSS changes (`AudioPlayerBar.razor.css`):** +- Adjusted volume cluster width constraints to accommodate the 24-bucket spectrum stacked above. +- Responsive layout unchanged at 600px breakpoint (single-row transport/volume with full-width seek below on narrow; same 3-zone layout on wide). + +**Scope:** +- Pure layout move; zero change to spectrum animation lifecycle, player logic, or seek gesture handling. +- Both `AudioPlayerBar` and `SpectrumVisualizer` components affected. +- Build clean: 0 errors, 0 new warnings. + +**Notes for future work:** +- `PlayerSeekZone` is now ready for the `WaveformSeeker` component (W1-T4/Phase 4 onwards). +- Volume cluster can comfortably accommodate 24 FFT bars; 32 would cause visual cramping (why the override exists). +- Spectrum visualization lifecycle (subscription to `StateChanged`, animation via `AudioInteropService.StartSpectrumAnimationAsync`) unchanged — only position in the DOM tree changed. + +--- + ## Phase 2 — Product surface: player and theming **Status:** Track card glass theming landed on 2026-06-05. AudioPlayerBar responsive unification and SpectrumVisualizer fix landed on 2026-06-05.