--- name: music-edit-to-length description: "Cut a music track to a target length on its downbeat grid with scored, click-free joins, writing .wav and a video-time beat grid (_edit.json, schema music-edit/1). Use on \"cut the music to 90 seconds\", \"fit the track to the video\", \"shorten this song on the beat\", \"re-cut the music edit\"." --- # music-edit-to-length Input: a `music-map/1` from `music-analysis` (run it first). Output: `.wav`, `_edit.json` and, with `--preview`, `.m4a` for listening. The edit file feeds `beat-sync-video` and the picture edit. Scripts run in the quick-tier venv (`.venv-music`, see `music-analysis` step 0); `PKG=/../../..`. ## Procedure 1. **Analyse** — `music-analysis` → `track_map.json`. Read the sections, classes and drop candidates; confirm the drop by ear. 2. **Identify blocks** — mark the sections and genre/energy blocks (e.g. tech-house groove bars 1–32, trance breakdown/build 33–65, groove again 66–105). Joins may only connect material from the same block family. 3. **Score joins** — ```bash .venv-music/bin/python "$PKG/.pi/skills/music-edit-to-length/scripts/score_joins.py" track_map.json \ --candidates auto --target-duration 90 --anchor-bar 66 .venv-music/bin/python "$PKG/.pi/skills/music-edit-to-length/scripts/score_joins.py" track_map.json --from-bar 12 --to-bar 17 ``` A join plays through the end of bar A and continues at bar B. Per factor: chroma and timbre similarity of the outgoing bars A−1..A against B's run-up in the source (B−2..B−1 — a match means the music arrives where B expects it), level jump, `section_boundary`, `class_change`. `score = 0.4·chroma + 0.4·timbre − 0.02·|jump dB| − 0.5·[groove/drop ↔ breakdown/build] + 0.1·[section boundary]`. Prefer ≥ 0.75 with no class change. The score is advisory: automatic classes cannot always tell a genre boundary (a trance build and a tech-house groove both have drums and bass) — your block marking in step 2 decides. 4. **Render** — ```bash .venv-music/bin/python "$PKG/.pi/skills/music-edit-to-length/scripts/edit_music.py" track.wav music/track_edit90 \ 1:13 17:25 25:33 66:82 102:197.0 --preview ``` The map defaults to `