The converter, spp2musicxml, implements what is described here; where this document and the converter differ, the converter is more likely right.
Starts with 2 bytes: the number of records. It can be more than the song's number of measures, and the records beyond are not used. Each record has the measure number SPP shows, which need not count from 1 by one: it can be set by hand (Objektarten: 1 to 90, then 109 to 119), it skips the measures a multi-measure rest stands for (tag 64), and Beethoven 5's finale, saved as its own song, starts at 374. Stopping at the record numbered like the first field, as the converter once did, goes wrong in those songs; the count holds in the whole corpus. Then one record per measure, 17 bytes, and when byte 16 is not 00, a list of measure tags starting with that byte, ended by a 00 tag.
| bytes | meaning
|
|---|
| 0-1 | measure number, as SPP shows it; songs can start at 0, and numbers can be skipped
|
| 2 | 04 when used, 00 when not
|
| 4-5 | number of note positions in the measure
|
| 11-12 | horizontal spacing?
|
After this header comes a list of zero or more tags, ending with 00
The list of tags has to be walked tag by tag to find its end.
Tag ff: ff, style, beat type, the previous beat type, beats, the previous beats, 00. The previous ones are 00 in the first measure: ff 04 04 00 03 00 00 is 3/4; ff 04 04 04 02 03 00 is 2/4 after 3/4.
| code | SPP shows
|
|---|
| 01 | C (common time, 4/4)
|
| 02 | cut C (2/2)
|
| 03 | another cut C
|
| 04 | the numbers
|
| 05 | two numbers added: 4+0/4 (bytes 4 and 5)
|
| 06 | three numbers added (bytes 4, 5 and 6)
|
Checked by loading copies of a song with each style in SPP. With the symbols, the beat bytes are left over from before; the nominal length (c8) is right.
Tag 3f, one byte, the bar line at the end of the measure:
| code | bar line at the end of the measure
|
|---|
| 00 | normal
|
| 01 | dotted
|
| 02 | normal, set explicitly
|
| 03 | double
|
| 04 | final (thin, thick)
|
| 05 | repeat end
|
| 06 | repeat start, of the next measure
|
| 07 | repeat end and start?
|
| 08 | repeat end and start (at a line break in Objektarten)
|
Checked against the Taktstriche measures of SPP's demo song Objektarten, as SPP prints them.
The same codes in measure tag 0c and note tag e4:
| code | clef
|
|---|
| 00 | treble
|
| 01 | bass
|
| 02 | tenor (C on the 4th line): only in bassoons and cellos (Beethoven 5, Dvořák 9)
|
| 03 | alto (C on the 3rd line): only in violas (Dvořák 9)
|
| 04 | treble, an octave down
|
| 05 | treble, an octave up (test song f0, with the clef dialogue's six clefs: treble, bass, alto, tenor, treble 8 below, treble 8 above, measure after measure; the codes 00 to 05 are the dialogue's treble, bass, C line 3 or 4, treble down, treble up, in the order of the table)
|
Right after the last measure record: exactly parts × measures records, part after part, and within a part measure after measure. Each record is a 4-byte length and the notes of that measure; an empty measure is 00 00 00 00. Checked: the number of records up to the guitar tuning is parts × measures + 7 in every file.
A measure with notes holds one or more notes, each starting with fe. SPP stores nothing for a measure without notes, and a whole rest for a measure rest, in any time signature. A measure can also be incomplete: SPP stores what is in it and leaves the rest empty, with no rests (Beethoven 5, part 3, measure 166: one quarter in 2/4).
There are two forms, told apart by byte 5.
| long | short | meaning
|
|---|
| 0 | 0 | note number, from 1
|
| 1-2 | 1-2 | horizontal position: byte 1 × 100 + byte 2
|
| 3 | 3 | 00
|
| 4 | 4 | note number - 1
|
| 5 | | number of tones (1 to 10)
|
| 5 | the short form: c7 quarter, c6 eighth, c5 16th
|
| 6 | | the left extent of the note on the page, in layout units: 00 for a plain note, 08 with an accidental, 07 for a note in parentheses (test song h2), the width of a displaced notehead or other signs to the left otherwise
|
| 7 | | the right extent, in layout units: 08 for a normal notehead, 06 for a cue note (h2), 0e (8 + 6) with a dot, 0f for a note in parentheses; in the other notes it is byte 6 plus 8. Changing bytes 6 and 7 in a song changes nothing on screen (test songs made from h2 with 0 to 60 in both, opened in SPP Lite 5.1): SPP lays the notes out itself, these are what it left from that
|
| 8-9 | | duration: byte 8 × 100 + byte 9
|
| 10 | 6 | note type
|
| 11 | 7 | stem, beam and rest
|
After this header comes a list of one or more tones, then a list of zero or more note tags, ending with 00
The short form is used only for a single note or rest (never a chord), a plain quarter, eighth or 16th, without dot, triplet or accidental: its duration is that of its type. Everything else uses the long form, also single notes. Checked over the corpus. The converter also copes with a dotted note in the short form (a dot tag and no duration to take it from); the corpus has none. The long form has the duration in bytes 8-9, which includes dots and triplets: a dotted half is 17 04, 2304; an eighth in a triplet 02 38, 256.
3 × level + variant + 1, plus 18 hex for a rest.
| level | note | code (plain)
|
|---|
| 0 | whole | 02
|
| 1 | half | 05
|
| 2 | quarter | 08
|
| 3 | eighth | 0b
|
| 4 | 16th | 0e
|
| 5 | 32nd | 11
|
| 6 | 64th | 14
|
| 7 | 128th | 17
|
Variant 0 is dotted (once or more: the duration says how often), 1 plain, 2 triplet. So 07 is a dotted quarter, 0c an eighth in a triplet, 20 a quarter rest. Checked with notes entered in SPP.
| bit | meaning
|
|---|
| 03 | beam
|
| 04 | stem down
|
| 08 | cue note, printed small: set on the Stichnoten of Objektarten, and in the figured bass realisations of Basso continuo and Generalbass
|
| 10 | rest
|
| 20 | dotted
|
Checked with step-entered eighths (01 02 01 02) and 16ths (01 00 00 02).
| code | beam
|
|---|
| 00 | continue (inside a beam), or none (quarters and longer)
|
| 01 | begin
|
| 02 | end
|
| 03 | a flag, no beam
|
Each tone is 3 bytes: staff position, MIDI pitch, velocity. A chord has all its tones after the header, before the tags.
- The staff position counts diatonic steps: C4 is 35 (
23 hex), D4 36. So the letter is "CDEFGAB"[position mod 7], the octave position / 7 - 1. Plus 100 when the note head is on the other side of the stem, as the upper note of a second.
- With the pitch, the position gives the spelling: F♯4 is
26 42, G♭4 would be 27 42. SPP spells the black keys entered on its keyboard as C♯, E♭, F♯, A♭, B♭.
- The position is the written note, the pitch the sounding one: for a transposing instrument they differ by the same number of steps throughout the part (Dvořák 9's clarinets and horns). Tablature, drum and accordion staves have positions that do not follow the pitch.
- Velocity: usually the same for a whole part (
4c, 69, 74). A rest entered in SPP is 32 00 00; rests are told by the rest bit, not by velocity 00.
| code | accidental
|
|---|
| 00 | none
|
| 01 | 𝄫
|
| 02 | ♭
|
| 03 | ♮
|
| 04 | ♯
|
| 05 | 𝄪
|
The first byte per tone of tag d6:
| code | tie
|
|---|
| 01 | start
|
| 02 | stop
|
| 03 | continue (stop and start)
|
| +04 | curved under
|
| +10 | curved over
|
The codes are the numbers of SPP's ottava menu (test song f1, one note under each choice, e2 NN 64; shown in SPP): 0 remove, 1 "8", 2 "8va", 3 "15", 4 "15va", 5 "-8", 6 "-8va", 7 "-15", 8 "-15va". The first four are drawn above the staff, the notes sounding higher than written; the last four below it, lower. With and without "va" (1 against 2, 3 against 4, 5 against 6, 7 against 8) only the text of the sign differs. The third byte is 64, or another number where the song has a line that extends (Czerny, Dvořák, Steirische Harmonika): not understood. The converter makes 1 and 2 an 8va, 3 and 4 a 15ma, 5 and 6 an 8vb, 7 and 8 a 15mb.
| code | sign | MusicXML octave-shift
|
|---|
| 01, 02 | 8, 8va, above | down, 8
|
| 03, 04 | 15, 15va, above | down, 15
|
| 05, 06 | -8, -8va, below | up, 8 (code 06 was once taken for bellows directions in Steirische Harmonika: it has the same varying third byte as other ottavas)
|
| 07, 08 | -15, -15va, below | up, 15
|
The first byte of each item of tag e5. Checked against the measures "Dynamik" and "Artikulation" of SPP's demo song Objektarten, where each mark sits on its own note, as SPP draws them:
| code | mark | MusicXML
|
|---|
| 52, 53, 54, 55, 56, 57, 58, 59 | ppp, pp, p, mp, mf, f, ff, fff | dynamics: ppp, pp, p, mp, mf, f, ff, fff
|
| 5a, 5b, 5c, 5d, 5e | sf, fz, sfz, ffz, fp | dynamics: sf, fz, sfz, other-dynamics ffz, fp
|
| 6c | staccato | articulations: staccato
|
| 6d | tenuto | articulations: tenuto
|
| 6e | a small wedge | articulations: spiccato
|
| 6f | accent (>); once taken for a diminuendo | articulations: accent
|
| 70 | V (an upside-down marcato?) | articulations: strong-accent, type="down"
|
| 71 | marcato (Λ) | articulations: strong-accent
|
| 72 | wedge | articulations: staccatissimo
|
| 73 | down-bow | technical: down-bow
|
| 74 | up-bow | technical: up-bow
|
| 75 | harmonic (o) | technical: harmonic
|
| 48, 49, 4a, 4b, 4c, 4d, 4e | fingerings 1 to 5, and 6 and 7 (4d and 4e: tried in SPP) | technical: fingering
|
From the songs of the SPP 1–4 format, saved by SPP 5.1, compared with son2emil's output of the originals (son2emil writes ornaments as i{…} and symbols as S{…}; per song, the counts agree):
| code | mark | MusicXML
|
|---|
| 48, 49, 4a, 4b, 4c | fingerings 1 to 5: as many of each as son2emil writes, in every song | technical: fingering
|
| 62 | inverted mordent (Pralltriller, son2emil's t2): as many as son2emil writes in every MEL song (7, 10, 8, 26 …) | ornaments: inverted-mordent
|
| 76, 77 | pedal down (Ped., son2emil's S{P}) and up (S{*}): Für Elise 34 and 33, a Chopin mazurka 7 and 7, Liebestraum 80 and 49 (son2emil 81 and 49). In Für Elise on the first and the fifth note of each measure of the left hand | direction: pedal (start, stop)
|
| 7a | coda (S{cod}), in 6 songs | direction: coda
|
| 7b | segno (S{seg}) | direction: segno
|
| 7d | D.S. (S{DS}) | direction: words D.S.
|
| 7e | ? 144 times in Liebestraum, among 76 and 77; son2emil writes nothing for it | none yet
|
From the Triller measure: 5f and 60 turns, 65 66 67 68 more ornaments (not decoded); 3b and 3d a ♭ and a ♯ above an ornament (the second turn has 3b as its second item).
Codes tried in SPP: the codes of the marks in Czerny's Etude op. 740 (the staccato 6c, in the second part, measures 17-19, 24-28, 50, 59 and 61) were changed to other codes, and the song was looked at in SPP Lite 5.1 (research/set_mark_codes.py; adding an e5 tag to a note did not work: SPP drew nothing). What each code draws:
| code | SPP draws
|
|---|
| 00, 01, 02 | a clef sign by the note: treble, bass, a C clef (the clefs of e4?)
|
| 12 | a flat sign above the note (tried in an old song: replacing a staccato of Mozart's CLAR1DL4 in SPP Lite 5.1)
|
| 13 | a natural sign above the note (in the Czerny test in one measure, in another nothing)
|
| 29 | a small treble clef sign
|
| 35, 96 | a short stroke before the note, like a small grace stroke
|
| 88, 90 | a short vertical stroke above the note (old song; 90 drew nothing in the Czerny test)
|
| 3f | a small flag-like hook above the note
|
| 4d, 4e | the fingerings 6 and 7 (above the note, like 48 to 4c for 1 to 5)
|
| 65 | a wavy line with a hook down at its start
|
| 66 | a wavy line with a small hook at its start
|
| 67 | a wavy line with a hook up at its end
|
| 68 | a wavy line with a vertical stroke through it
|
| 6b | a small wavy line below the note (old song)
|
| 7e | a small rest-like zigzag below the note (old song; 144 times in Liebestraum)
|
| 84 | a small bass clef sign above the note
|
| 97 | a small arc above the note
|
| 98 | a plus sign above the note (a stopped note)
|
| 05, 28, 2f, 36, 90 | nothing that could be seen: probably signs for playback only, or hidden
|
Used by the converter, but not checked against SPP: 6a a trill (2 bytes more), 78 fermata above, 79 fermata below, 99 the text "cresc.". Still unknown: 63 and 88. The hairpins are not e5 marks but note tag d1.