Skip to content

Stretch quality upgrade: R3 engine, hybrid/repitch/slice modes, pipeline hygiene - #1

Merged
thomasjohnflaherty merged 7 commits into
mainfrom
stretch-quality-upgrade
Jun 12, 2026
Merged

Stretch quality upgrade: R3 engine, hybrid/repitch/slice modes, pipeline hygiene#1
thomasjohnflaherty merged 7 commits into
mainfrom
stretch-quality-upgrade

Conversation

@thomasjohnflaherty

Copy link
Copy Markdown
Owner

Motivation

Large slow-downs (e.g. 170 -> 90 BPM) were distorting and fragmenting under the legacy R2/crispness path. This PR upgrades the whole stretching pipeline around that problem.

Changes

1. R3 engine by default — rubberband version is detected and the R3 engine (--fine --centre-focus, Breakfastquay's max-quality offline recipe) is used when rubberband >= 3. New --engine auto|r2|r3 flag; r3 errors clearly on older rubberband. --crispness now applies to --engine r2 only (ignored under R3).

2. New processing modes--mode stretch|repitch|hybrid|slice, default hybrid:

  • hybrid: repitch up to --max-semitones (default 3.0), then stretch the remainder — splits the artifact load; identical to stretch when the tempo change is within 1.4x
  • repitch: vinyl-style speed change via resampling (pitch follows tempo, no rubberband)
  • slice: slice-and-shift at detected onsets with equal-power crossfades — transients bit-exact on slow-downs, no rubberband

3. BPM filename detection — space-separated trailing BPM now parses (Hydro Break 170.wav -> 170) instead of falling back to unreliable librosa auto-detection; output naming strips the same pattern.

4. Converter hygiene — clip guard on mono downmix (peak-normalize only on overflow), TPDF dither on PCM_16 writes, and a no-op skip that copies instead of decode/re-encode when no conversion is needed.

Listening tests

Quality was validated by A/B renders of real breaks at large slow-downs (e.g. 170 -> 90) across engine/crispness/mode combinations, kept locally under outputs/ab/ (not committed; outputs/ is now gitignored).

Tests

58 -> 121 tests, all passing; ruff check and format clean.

🤖 Generated with Claude Code

thomasjohnflaherty and others added 5 commits June 12, 2026 11:41
"Hydro Break 170.wav"-style names now parse as 170 BPM instead of
falling back to unreliable librosa auto-detection, and the BPM strip
in output naming accepts the same separator. 90-180 range check
unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Detect the installed rubberband major version and use the R3 engine
(--fine --centre-focus, Breakfastquay's max-quality offline recipe) when
rubberband >= 3. R3 is markedly better than R2 for percussive material
at large stretch ratios. --engine auto|r2|r3 selects explicitly; r3
errors clearly on older rubberband, and crispness now applies to the
R2 path only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
repitch: vinyl-style speed change via resampling (pitch follows tempo,
no rubberband). hybrid: repitch up to a semitone budget, then stretch
the remainder, splitting the artifact load between pitch change and
stretching; identical to a pure stretch when the tempo change is
within 1.4x.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
slice: slice-and-shift (the ReCycle/jungle method) - cut at detected
onsets and re-space slices on the timeline with equal-power crossfades,
keeping transients bit-exact on slow-downs without rubberband.

Expose --mode stretch|repitch|hybrid|slice (default hybrid),
--max-semitones, and --engine on the CLI, dispatch modes in
process_file, and document the new controls in README and CLAUDE.md.
CLI/processor wiring and docs for the engine and repitch/hybrid
commits land here because the changes share hunks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Peak-normalize only on overflow so mono downmixes cannot wrap on
integer write, apply TPDF dither when writing PCM_16, and skip the
decode/re-encode round trip entirely when no conversion is needed.
Also record the release notes in CHANGELOG and ignore outputs/ plus
Claude session artifacts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

thomasjohnflaherty and others added 2 commits June 12, 2026 11:48
- actions/checkout v4 -> v6
- actions/setup-python v5 -> v6
- astral-sh/setup-uv v7 -> v8 (uv pin 0.9.22 -> 0.11.21)
- codecov/codecov-action v4 -> v7 (file -> files input rename)
- softprops/action-gh-release v2 -> v3
- Sync version references in .claude/rules/cicd.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@thomasjohnflaherty
thomasjohnflaherty merged commit c4c1d70 into main Jun 12, 2026
2 checks passed
@thomasjohnflaherty
thomasjohnflaherty deleted the stretch-quality-upgrade branch June 12, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants