What's wrong
QualitySuffix in Semantics.Music/Key.cs has these arms:
SeventhType.Diminished => chord.Quality == ChordQuality.Diminished ? "" : "7",
...
ChordQuality.Diminished => "°",
This produces two wrong results:
- A fully diminished seventh (Diminished quality with a Diminished seventh) gets "°" plus an empty suffix, so
Bdim7 becomes vii°. That is the same numeral a plain Bdim triad gets, so the seventh is lost.
- A half-diminished seventh (
m7b5, which is Diminished quality with a Dominant seventh) gets "°7". But ChordFromRomanNumeral("vii°7") reads "°" as "dim" and builds Bdim7, the fully diminished chord. RomanNumeralParseTests.Parse_LeadingToneDiminishedSeventh asserts that reading, so the round trip changes the chord.
Repro (C major)
Key c = Key.Create(PitchClass.Create(0), Mode.Major);
c.RomanNumeralOf(Chord.Parse("Bdim")); // "vii°"
c.RomanNumeralOf(Chord.Parse("Bdim7")); // "vii°" expected "vii°7"
c.ChordFromRomanNumeral(c.RomanNumeralOf(Chord.Parse("Bm7b5")));
// "vii°7" -> Bdim7 (Seventh = Diminished, 9-semitone seventh); expected half-diminished (10 semitones)
This was reproduced with a temporary MSTest on net10.0 at 8c06aba.
Why it matters
The two sevenths on the leading tone are the most common place Roman-numeral analysis has to tell fully diminished and half-diminished apart: vii°7 in minor, viiø7 in major. Right now a triad and a diminished seventh get the same label. A half-diminished chord also changes identity when it goes through RomanNumeralOf and then ChordFromRomanNumeral.
Suggested fix / acceptance criteria
QualitySuffix emits °7 for Diminished + Diminished seventh and ø7 for Diminished + Dominant seventh (half-diminished).
ChordFromRomanNumeral reads ø (and ø7) as m7b5.
vii°7 and viiø7 are added to Parse_IsInverseOfRomanNumeralOf, so both survive the round trip.
This is separate from #281, which is about Chord.Parse("C°7").
What's wrong
QualitySuffixinSemantics.Music/Key.cshas these arms:This produces two wrong results:
Bdim7becomesvii°. That is the same numeral a plainBdimtriad gets, so the seventh is lost.m7b5, which is Diminished quality with a Dominant seventh) gets "°7". ButChordFromRomanNumeral("vii°7")reads "°" as "dim" and buildsBdim7, the fully diminished chord.RomanNumeralParseTests.Parse_LeadingToneDiminishedSeventhasserts that reading, so the round trip changes the chord.Repro (C major)
This was reproduced with a temporary MSTest on net10.0 at 8c06aba.
Why it matters
The two sevenths on the leading tone are the most common place Roman-numeral analysis has to tell fully diminished and half-diminished apart: vii°7 in minor, viiø7 in major. Right now a triad and a diminished seventh get the same label. A half-diminished chord also changes identity when it goes through
RomanNumeralOfand thenChordFromRomanNumeral.Suggested fix / acceptance criteria
QualitySuffixemits°7for Diminished + Diminished seventh andø7for Diminished + Dominant seventh (half-diminished).ChordFromRomanNumeralreadsø(andø7) asm7b5.vii°7andviiø7are added toParse_IsInverseOfRomanNumeralOf, so both survive the round trip.This is separate from #281, which is about
Chord.Parse("C°7").