Repository navigation
feat(theory): extended roman numerals + voice-led progressions for the first song - #377
Merged
Merged
Conversation
…e first song Per docs/BRIEF-progressions-for-first-song.md: - roman() accepts any chord() quality as a suffix (IVmaj7, vi9, ii11, Iadd9, Vsus4, bVIImaj7, bVImaj7); the numeral's case sets the third. Bare/7 numerals stay diatonic. chord() and roman() now share one root+quality builder (_build/_apply_voicing). - set_progression applies `voicing` to roman numerals too (was ignored when key was given). - Voice leading (default on): the first chord keeps its voicing, each next chord is re-voiced for least movement (common tones held, lowest note C3..C5, no semitone clusters). `bass=True` adds the root / slash bass as its own voice in C2..B2. - Fix: "ø7"/"°7" normalised to m7b5/dim7 (Bø7 raised "unknown quality m7b57"). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Production gate (core): ✅ PASS
|
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.
Implements
docs/BRIEF-progressions-for-first-song.md(included). Hard stop met: "8 bars in D: IVmaj7 V iii vi, then bVIImaj7 IV ii9 Iadd9, voice-led, open voicing, 1 bar each" plays smoothly on a pad (Pigments "Warm Pad"). Confirmed by ear.Changes
roman()now accepts anychord()quality as a suffix:IVmaj7,vi9,ii11,Iadd9,Vsus4,bVIImaj7,bVImaj7. Lower case makes the chord minor (vi9is a minor 9) unless the suffix already sets the third (dim/ø/sus/…). A bare numeral, or one with only a7, is still diatonic, soV7is the dominant 7th andbVII7is a dominant B♭7.chord()androman()now build chords with the same code (_build/_apply_voicing).voicingnow applies to roman numerals inset_progression. Before, it was ignored wheneverkeywas given.voice_lead=True, the default). The first chord keeps its voicing. Each later chord is re-voiced to move as little as possible from the one before: shared notes stay put, the lowest note stays between C3 and C5, and two notes a semitone apart get a penalty.bass=Trueadds the root (or the slash bass) as its own voice in C2–B2. A slash bass always stays underneath and is never voice-led. The logic lives in the puretheory.progression(), so tests run without the app.ø7/°7now normalise correctly.Bø7used to raise "unknown quality m7b57".set_progressionis now voice-led by default.voice_lead=Falserestores the old block chords.Verification
uv run --directory mcp test_theory.py: all 12 groups pass. Newtest_roman_extendedandtest_voice_leadingcover the brief's cases: F A C E, B♭ D F A, and no voice moving more than a 4th.test_mcp_parity.pyandtest_mcp_arg_parity.pypass.set_progression, read it back withget_clip(8 bars, expected voicings), and listened to the voice-led, +bass and block versions side by side.🤖 Generated with Claude Code