Stretch quality upgrade: R3 engine, hybrid/repitch/slice modes, pipeline hygiene - #1
Merged
Merged
Conversation
"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>
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 ☂️ |
- 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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|r3flag;r3errors clearly on older rubberband.--crispnessnow applies to--engine r2only (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 tostretchwhen the tempo change is within 1.4xrepitch: 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 rubberband3. 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