Chromatic pitch data type

MNX encodes chromatic pitches in a microsyntax. Some examples:

Chromatic pitchEncoding
Middle CC4
The C-sharp above middle CC#4
The D-flat above middle CDb4
The D-double-flat very near middle CDbb4
The pitch one quarter-tone above middle CC4+0.5
The pitch one quarter-tone above middle C (identical to the above, but expressed in whole tone units)C4+0.25w
The pitch one quarter-tone above middle C (identical to the above, but expressed as whole tone fraction)C4+1/4w
The pitch one quarter-tone above middle C (identical to the above, but expressed as octave fraction)C4+1/24o

Algorithm for parsing

To parse a chromatic pitch, use the following procedure:

  1. Let input be the string being parsed.
  2. Let position be a pointer into input, initially pointing at the start of the string.
  3. Let alteration be 0.
  4. If the character at position is not an uppercase ASCII letter in the range from U+0041 UPPERCASE A - U+0047 UPPERCASE G, return an error.
  5. Let step be the character at position, and advance position by 1.
  6. If the character at position is U+0023 HASH,
    1. While the character at position is U+0023 HASH,
      1. Increase alteration by 1.
      2. Advance position by 1.
  7. Else, if the character at position is U+0062 b,
    1. While the character at position is U+0062 b,
      1. Decrease alteration by 1.
      2. Advance position by 1.
  8. Collect a sequence of characters that are ASCII digits only and let unparsed number be the result.
  9. Let octave be the result of parsing unparsed number using the rules for parsing integers.
  10. Let alteration factor be 0.
  11. If the character at position is U+002B PLUS,
    1. Set alteration factor to 1.
    2. Advance position by 1.
  12. If the character at position is U+002D HYPHEN-MINUS,
    1. Set alteration factor to -1.
    2. Advance position by 1.
  13. If alteration factor is not equal to zero,
    1. Collect a sequence of characters that are ASCII digits, U+002E FULL STOP, or U+002F SLASH and place the result in unparsed number.
    2. If the character at position is U+006F LOWERCASE o,
      1. Multiply alteration factor by 12.
      2. Advance position by 1.
    3. Else, if the character at position is U+0077 LOWERCASE w,
      1. Multiply alteration factor by 2.
      2. Advance position by 1.
    4. If unparsed number contains U+002F SLASH, parse it as a rational number. Otherwise parse it as a valid floating-point number. Multiply the result by alteration factor and add this to alteration.
  14. If position is not at the end of the string, return an error.
  15. Return step, octave and alteration.