Skip to content

Chord.ToString() writes non-standard symbols: G9 → "G79", Gmaj9 → "Gmaj79", G13 → "G713", G7sus4 → "Gsus47", C6/9 → "C6add9" #358

Description

@matt-edmondson

What's wrong

AppendQualityAndSeventh writes 7/maj7 first (Chord.cs#L590-L624). AppendTensions then appends the natural extension number after it (Chord.cs#L645-L688). The resulting "canonical symbol" is not something any chart uses:

Parsed from ToString()
C9 / Cm9 / Cmaj9 / Caug9 C79 / Cm79 / Cmaj79 / Caug79
C11 / C13 / Cmaj13 C711 / C713 / Cmaj713
C7sus4 / C9sus4 Csus47 / Csus479
C6/9 / Cm6/9 C6add9 / Cm6add9

Progression.Parse("4/4 Dm9 | G13 | Cmaj9 | G7sus4").ToString() gives "4/4 Dm79 G713 Cmaj79 Gsus47". Section.ToString() and Arrangement.ToString() inherit the same output.

Parse(ToString()) still round-trips, and the round-trip corpus (ChordRoundTripTests.cs) compares only the parsed structure. Because no test pins the text, this was never caught. The type-safe factories spec calls the output a "canonical symbol (e.g. Cmaj7, C/G)" (spec L95-L153).`` A chart format meant for people should print what a musician writes.

Suggested fix

  • When a natural extension number is emitted for a seventh chord, let it replace the 7: dominant 7+9 becomes 9, and maj7+9 becomes maj9.
  • Put sus after the number: 7sus4, 9sus4.
  • Write a 6 with an added 9 as 6/9, which Chord.Parse already accepts.

Coordinate with #300, which reworks the same AppendTensions branch for 7add13. That issue is about losing the round-trip; this one is the ordinary C9 → C79 case.

Acceptance criteria

  • ToString() returns C9, Cm9, Cmaj9, C11, C13, Cmaj13, C7sus4, C9sus4, C6/9 and Cm6/9 for the inputs in the table.
  • The round-trip corpus gains a text assertion, Parse(s).ToString() == s for canonical inputs, alongside the structural one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions