Auto-settings engine: convert(auto=...) planner + scorer - #38
Open
yumiaura wants to merge 1 commit into
Open
Conversation
Introduce convert(auto=True): the pipeline picks source, method, voices, transpose and duty from the song's own features instead of the user guessing. No CLI surface yet - this is the engine; the --auto flag and docs follow. Why a hybrid rather than "render everything and keep what passes": the two validators are not on one scale (validate_audio has 4 weak checks that almost everything clears; validate_melody has 9 strict ones; alias/clip are ~0% for every mode by construction). So a scored search across families would always favour chords/band/nes over lead. Instead: - Cross-family choice is made by rules on cheap content features - polyphony (estimate_polyphony) picks lead vs a fuller arrangement, drum density (drum_density) picks chords vs a drum-backed band, and a dense steady beat upgrades band to the beat-quantised nes (choose_voices). - transpose is a uniform octave shift centring the median note on the ringtone register (choose_transpose), so pitch classes and harmony survive. - Only the duty cycle is a scored micro-search (score_render): it changes timbre and aliasing but not the arrangement, so its candidates are comparable within the chosen family. 0.25 is tried first so it wins score ties and output stays deterministic. Refactor: the four per-branch render bodies move verbatim into a disk-free render_events() helper returning (samples_u8, quality_ok, report_lines), so the planner can render several duty candidates off one shared Demucs separation and one basic-pitch transcription and keep only the best. convert() writes the winner once. The arrangement settings now take None as a "not set" sentinel: under auto the planner fills the unset ones (explicit values always win); without auto an unset value falls back to its module default, so existing callers and the current CLI behave exactly as before. Verified on the instrumental test track: auto selects instrumental/nes with a centred register and E-minor key, all quality checks pass, two runs are byte-identical (deterministic), an explicit --voices chords is honoured while the rest is still auto-picked, and the non-auto default render is unchanged.
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.
Summary
Phase A of the
--autofeature (engine only; the CLI flag + docs land in thestacked Phase B PR). Adds
convert(auto=True), which pickssource,method,voices,transposeanddutyfrom the song's own features instead of the userguessing.
Why hybrid, not "render everything and keep what passes": the two validators
are not on one scale —
validate_audio(chords/band/nes) has 4 weak checks thatalmost everything clears;
validate_melody(lead/pitch) has 9 strict ones; andalias/clip are ~0% for every mode by construction. A scored search across families
would therefore always favour chords/band/nes over lead. So:
estimate_polyphonypicks lead vs a fuller arrangement,
drum_densitypicks chords vs a drum-backedband, and a dense steady beat upgrades band to the beat-quantised nes
(
choose_voices).register (
choose_transpose) — pitch classes and harmony survive.score_render): it changes timbre andaliasing but not the arrangement, so its candidates are comparable within the
chosen family. 0.25 is tried first so it wins ties and output stays deterministic.
Refactor: the four per-branch render bodies move verbatim into a disk-free
render_events()helper, so the planner renders several duty candidates off oneDemucs separation + one basic-pitch transcription and keeps the best;
convert()writes the winner once. Arrangement settings now take
Noneas a "not set"sentinel — under auto the planner fills the unset ones (explicit values always
win); without auto they fall back to module defaults, so existing callers and the
current CLI are unchanged.
Test plan
convert("input.mp3", auto=True)selects instrumental/nes, centred register(transpose +24), E-minor key; all 4 quality checks pass.
d5a2632…).auto=True, voices="chords"keeps chords, still auto-picks the rest.python -c "import audio8bit.cli"smoke-imports (CI parity).