-
feat(foundry): the loop grader (engine/grade.py) — the katana (#10) · edb62258
A pure grade(wav) -> LoopGrade that scores ANY sample against the empirical A-profile + the B mechanical rulebook (PHASE2_FINDINGS §2-§3, §5a): seam click, zero-crossing cleanliness, DC offset, bar-length self-consistency, level sanity, bass mono-compatibility, and the one-shot/loop class. Composite 0-1 → S/A/B/C/D tier + per-rule sub-scores + human-readable flags. This is step 1 of the phase-2 build order — the instrument the finder (#5) and the Hall of Fame tierlist (#11) both reuse (DRY, feedback_build_katana_first): the finder grades hypothetical windows, the tierlist grades existing files, same sub-scorers. Two findings while validating against real ParVagues loops (crimewave/diams_dj/humpty): 1. bar-consistency was DEAD — `librosa.feature.rhythm.tempo` doesn't exist in librosa 0.11 (it's `librosa.feature.tempo`), so a swallowed AttributeError sent every file down the no-tempo fallback → a flat 0.50 for all. Fixed; now crimewave drums correctly reads as 4 bars @ 121.9 bpm (matches the GT note ~121.8). 2. seam was measuring the single-sample wrap step |x0-x[-1]| vs the signal's MEAN step — which unfairly punishes a loop for wrapping at a zero crossing (the steepest point: a *perfect* integer-period sine scored only 0.40). §3 wants waveform CONTINUITY, so seam now measures the second difference (jerk) at the wrap, |x0 - 2·x[-1] + x[-2]|, normalized by typical curvature — captures both a value jump and a slope break, and a clean wrap now grades ~1.0. Sanity: crimewave (a core-palette kit) lands mostly B-tier or above, with clipping /off-grid cuts correctly sunk to D — consistent with §5b's "core kits must tier high" validation target. The composite WEIGHTS + THRESH are tagged v1/provisional: the dc-offset flag is still noisy (1e-4 is spec-strict) and the seam dB cutoffs want calibrating — that's #11's job (corpus-wide grade
↔ .tidal-usage correlation), not eyeball-tuning on 3 kits. 28 tests pass (synthetic signals, relative assertions). Runs under system python3 (numpy/scipy/soundfile/librosa already present); no GPU, no network. CLI: python3 -m engine.grade <wav>… [--json].PLN (Algolia) authorededb62258
×