Unicode Piano Roll language spec

Draft Version 2024-01-04

UPR text is in UTF-8, and each line ends with \n .

Each line can be parsed individually, and parses to one of these four node types: RollHeader , RollFooter , BarHeader , and BarRow .

A Roll contains a list of those nodes that starts with a RollHeader , ends with a RollFooter , and contains any combination of BarHeader s and BarRow s in the middle.

Example work

Here's the first three bars of ErlkΓΆnig, by Franz Schubert:

🎼 4/4, g minor, 🎹:🎹
 β”Œβ”€β”€β”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΅β”€β”€β”€β”€β”€β”€β”€β”€β” ΒΉ
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”œβ”€β”€β”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΅β”€β”€β”€β”€β”€β”€β”€β”€β”€ Β²
β–·β”Š3           G                       β”Š      G           G             β”Š
 β”Š3             A                     β”Š      G           G             β”Š
 β”Š3              BΜ²                    β”Š      G           G             β”Š
β–·β”Š3                C                  β”Š      G           G             β”Š
 β”Š3                  D                β”Š      G           G             β”Š
 β”Š3                   EΜ²               β”Š      G           G             β”Š
β–·β”Š3                  D                β”Š      G           G             β”Š
 β”Š3                  β–΄                β”Š      G           G             β”Š
 β”Š3                  |                β”Š      G           G             β”Š
β–·β”Š3              BΜ²                    β”Š      G           G             β”Š
 β”Š3              β–΄                    β”Š      G           G             β”Š
 β”Š3              |                    β”Š      G           G             β”Š
 β”œβ”€β”€β”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΅β”€β”€β”€β”€β”€β”€β”€β”€β”€ Β³
β–·β”Š3           G                       β”Š      G           G             β”Š
 β”Š3           β–΄                       β”Š      G           G             β”Š
 β”Š3           |                       β”Š      G           G             β”Š
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
β–·β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β”Š3                                   β”Š      G           G             β”Š
 β•˜β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•§β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•›

Example lines

(TODO: better formatting on mobile, mobile-vs-desktop styling)

UPR line Parsed
"🎼 4/4, C major, 🎹:🎹🎀\n" β†’ { _type: "RollHeader", time_signature, key_signature_name, staff_context }
" β”Œβ”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”Όβ”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β” ΒΉ\n" β†’ { _type: "BarHeader", is_first_row: true, staff_widths: [18, 16], staff_firstkeynums: [33, 45], bar_label: 1 }
" β”œβ”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”Όβ”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€ Β²\n" β†’ { _type: "BarHeader", is_first_row: false, staff_widths: [18, 16], staff_firstkeynums: [33, 45], bar_label: 2 }
" β”Š B β”Š β”Š\n" β†’ { _type: "BarRow", is_beat: false, is_triplet: false, staff_content: [{ cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0] }, { cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] }] }
β–·β”Š3 β–΄ β”Š β”Š\n { _type: "BarRow", is_beat: true, is_triplet: true, staff_content: [{ cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,102,0,0,0] }, { cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] }] }
β•˜β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•§β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•›\n { _type: "RollFooter", staff_widths: [18, 16] }

Table of contents for the rest of this document

Example work
RollFooter
BarHeader
BarRow
β†’ cell values
RollHeader
β†’ TimeSignature
β†’ KeySignatureName
β†’ StaffContext

RollFooter

Examples

UPR line Parsed
β•˜β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•§β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•›\n { _type: "RollFooter", staff_widths: [18, 16] }

Definition

TODO

Unicode codepoints

Number Text Name UTF-8
U+000A LINE FEED (LF) 0A
U+0020 SPACE 20
U+2558 β•˜ BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE E2 95 98
U+2550 ═ BOX DRAWINGS HORIZONTAL DOUBLE E2 95 90
U+2567 ╧ BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE E2 95 A7
U+255B β•› BOX DRAWINGS UP SINGLE AND LEFT DOUBLE E2 95 9B

BarHeader

Examples

UPR line Parsed
β”Œβ”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”Όβ”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β” ΒΉ\n { _type: "BarHeader", is_first_row: true, staff_widths: [18, 16], staff_firstkeynums: [33, 45], bar_label: 1 }
β”œβ”€β”€β”€Β²β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€Β³β”€β”€β”Όβ”€β”€β”€Β³β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β΄β”€ Β²\n { _type: "BarHeader", is_first_row: false, staff_widths: [18, 16], staff_firstkeynums: [33, 45], bar_label: 2 }

Definition

TODO

Unicode codepoints

Number Text Name UTF-8
U+000A LINE FEED (LF) 0A
U+0020 SPACE 20
U+250C β”Œ BOX DRAWINGS LIGHT DOWN AND RIGHT E2 94 8C
U+2500 ─ BOX DRAWINGS LIGHT HORIZONTAL E2 94 80
U+2510 ┐ BOX DRAWINGS LIGHT DOWN AND LEFT E2 94 90
U+251C β”œ BOX DRAWINGS LIGHT VERTICAL AND RIGHT E2 94 9C
U+253C β”Ό BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL E2 94 BC
U+2524 ─ BOX DRAWINGS LIGHT VERTICAL AND LEFT E2 94 A4
U+2070 ⁰ SUPERSCRIPT ZERO E2 81 B0
U+00B9 ΒΉ SUPERSCRIPT ONE C2 B9
U+00B2 Β² SUPERSCRIPT TWO C2 B2
U+00B3 Β³ SUPERSCRIPT THREE C2 B3
U+2074 ⁴ SUPERSCRIPT FOUR E2 81 B4
U+2075 ⁡ SUPERSCRIPT FIVE E2 81 B5
U+2076 ⁢ SUPERSCRIPT SIX E2 81 B6
U+2077 ⁷ SUPERSCRIPT SEVEN E2 81 B7
U+2078 ⁸ SUPERSCRIPT EIGHT E2 81 B8
U+2079 ⁹ SUPERSCRIPT NINE E2 81 B9

BarRow

Examples

UPR line Parsed
β”Š B β”Š β”Š\n { _type: "BarRow", is_beat: false, is_triplet: false, staff_content: [{ cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0] }, { cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] }] }
β–·β”Š3 β–΄ β”Š β”Š\n { _type: "BarRow", is_beat: true, is_triplet: true, staff_content: [{ cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,102,0,0,0] }, { cells: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] }] }

Definition

TODO

Unicode codepoints

Number Text Name UTF-8
U+000A LINE FEED (LF) 0A
U+0020 SPACE 20
U+0031 1 DIGIT ONE 31
U+0033 3 DIGIT THREE 33
U+0036 6 DIGIT SIX 36
U+0038 8 DIGIT EIGHT 38
U+0041 through U+0047 A through G LATIN CAPITAL LETTER + ( A through G ) 41 through 47
U+0058 X LATIN CAPITAL LETTER X 58
U+007C | VERTICAL LINE 7C
U+0305 (n/a) COMBINING OVERLINE CC 85
U+0332 (n/a) COMBINING LOW LINE CC B2
U+250A β”Š BOX DRAWINGS LIGHT QUADROUPLE DASH VERTICAL E2 94 8A
U+25B4 β–΄ BLACK UP-POINTING SMALL TRIANGLE E2 96 B4

cell values

For each UPR staff within a bar, there is a mapping from column index to key number. This is what determines the key numbers of the notes that get played.

This means the non-blank cell values don't need to be labelled with a name of the note.

So why are they?

Examples

ID Text
0 .Blank Nothing should be playing for this key number
101 | .Continuation The already-playing note in this column continues
102 β–΄ .Continuation_stacc_up The already-playing note in this column (1) continues, and (2) should have been played staccatissimo
(1 << 3) | 0 C .C
(2 << 3) | 1 CΜ… .C_sharp
(2 << 3) | 2 DΜ² .D_flat
(2 << 3) | 0 1Μ…Μ² .AboveC Key class index 1 (0-based), but without indicating any preference for the name Cβ™― vs Dβ™­
(3 << 3) | 0 D .D
(4 << 3) | 1 DΜ… .D_sharp
(4 << 3) | 2 EΜ² .E_flat
(4 << 3) | 0 3Μ…Μ² .AboveD Key class index 3 (0-based), but without indicating any preference for the name Dβ™― vs Eβ™­
(5 << 3) | 0 E .E
...
(7 << 3) | 0 6Μ…Μ² .AboveF Key class index 6 (0-based), but without indicating any preference for the name Fβ™― vs Gβ™­
...
(9 << 3) | 0 8Μ…Μ² .AboveG Key class index 8 (0-based), but without indicating any preference for the name Gβ™― vs Aβ™­
...
(11 << 3) | 0 XΜ…Μ² .AboveA Key class index 10 (0-based), but without indicating any preference for the name Aβ™― vs Bβ™­
...

RollHeader

Examples

UPR line Parsed
🎼 4/4, C major, 🎹:🎹🎀\n { _type: "RollHeader", time_signature, key_signature_name, staff_context }

Definition

TODO

Unicode codepoints

Number Text Name UTF-8
U+000A LINE FEED (LF) 0A
U+0020 SPACE 20
U+002C , , 2C
U+002F / / 2F
U+003A : : 3A
U+0030 through U+0039 0 through 9 DIGIT ONE .. DIGIT NINE 30 through 39
U+0041 through U+005A A through Z LATIN CAPITAL LETTER A .. LATIN CAPITAL LETTER Z 41 through 5A
U+0061 through U+007A a through z LATIN SMALL LETTER A .. LATIN SMALL LETTER Z 61 through 7A
U+266D β™­ MUSIC FLAT SIGN E2 99 AD
U+266F β™― MUSIC SHARP SIGN E2 99 AF
U+1F3BC 🎼 MUSICAL SCORE F0 9F 8E BC
U+1F3B9 🎹 MUSICAL KEYBOARD F0 9F 8E B9
U+1F3A4 🎀 MICROPHONE F0 9F 8E A4

TimeSignature

TODO

KeySignatureName

TODO

StaffContext

TODO

Performances

Unicode Piano roll example that includes performance intensities

TODO