Skip to main content

Score Perfect Professional 5-7 file format

Article by Maarten Tromp | Published | 8865 words

This document describes the *.son file format of Score Perfect Professional starting at version 5, as far as it is known.

Background information on the project can be found on the project page. This document describes the .son files of Score Perfect Professional (SPP) 5.0 to 7.0 (7.0 assumed, see Versions), as far as they are understood: enough to convert most songs to MusicXML, not everything a song can hold. Each finding says how it was checked. What is still unknown is listed under Open questions.

The converter, spp2musicxml, implements what is described here; where this document and the converter differ, the converter is more likely right.

In this article:

Open questions

Roughly in order of importance for the conversion:

Conventions

Text

Text in lyrics and free texts is Windows-1252, except that the characters from c8 up are written as two bytes: c7, then the character minus 100 (64 hex). So é (e9) is c7 85, ü (fc) is c7 98, ß (df) is c7 7b. Probably because the bytes from c8 up are tags. Bytes 00 are padding. The part names use the same escape.

The strings in the header are plain Windows-1252.

File layout

The header, the settings block (166 bytes, in all 203 songs of SPP 5.0 to 7.0) and the measures block on are read at fixed places, record by record. In between, the staff block is not read through: its first record ends with the 10 bytes f4 01 80 00 32 00 d0 07 ff ff (20 instead of 80 and e8 03 instead of d0 07 in some), after its pictures (a picture is found by BM and its size, as it can hold those 10 bytes); the pages and systems after that are skipped, as the part records come last and are found by the number 1.0 in them (Staff block); the measures start right after them. When a measure tag is unknown, the start of the notes is searched for as the first fe 01 00, which goes wrong in a song that starts with empty measures (no song has that now).

blockcontentshow it is found
headermagic, strings, fonts, countsfixed layout
settingsrecords separated by ff ff166 bytes after the counts, then fe ff ff ff
staff blockrecords separated by ff ff: system layout, one record per part, the chord list (optional), then the pictures (optional)up to the start of the measures block
measuresone record per measureright after the last part record: the part records are found by the number 1.0 as a double in them and are 76 bytes each (plus their extra items), so the end of the last is the start of the measures. (The converter used to search for a run of ff and 00 and correct that by trial, which was off by up to 88 bytes in 3 songs.)
notesone record per part per measureright after the last measure record
texts and part groups7 recordsright after the notes
part namesthe guitar tuning, then the part namesright after the part groups
tailmixer (master volume, 16 channels), markersafter the part names

Versions

SPP 5.0, 5.1 Lite, 5.2, 6.0 and 7.0 write the same format; the version that saved a file is in its header strings (05.00-002-0010 to 07.00-001-0050 in the corpus).

Each version reads the files of the earlier ones. The tags a file holds depend more on what is in the song than on the version.

Differences found between the versions so far:

SPP 6.0

SPP 6.0 adds a chord list when the song has chord symbols. SPP 6.0 stores a name, probably the registered owner, after the chord list.

SPP 7.0

SPP 7.0 is assumed to write the same format, possibly with tags that are new. No song made with it is in the corpus. It was tested by opening two small test songs (one and two parts) in SPP 7.0 under Wine and saving them again, next to the same songs saved by SPP 6.0. The files have the same container, the same tags and the same notes, and the converter reads them as the originals. The differences:

whereSPP 6.0SPP 7.0
version string06.00-001-002407.00-001-0050
the settings record at the start of the staff block, after 02 00 01 31nothing26 more bytes, in a song of one part and one of two: 16 00 00 00 00 07 00 00 27 10 27 10 and 14 bytes 00. 27 10 is 10000, probably 100.00 %, as in the spread of the counts (8000 is 80 %); the rest is unknown
the numbers of 2 bytes in the per measure layout part of the staff block (the places of the measures)xx + 102 (66) for most of them (29 and 34 values in the two songs); the reason is unknown

What the new data is for is not known. Scoretec's page on SPP 7.0 names two new things that are saved with the song: function buttons that can be tied to a page or a measure of the song ("Seitenbezogene und taktbezogene Funktions-Buttons werden mit dem Song zusammen abgespeichert"). The test songs have no buttons, so the 26 bytes are probably the room for them; not tested. The converter does not use any of these.

Other editions

The three editions, Professional (SPP), Standard (SPS) and Education (SPE), exist from version 4.0 at least (Scoretec: demos "in den Ausführungen Education, Standard und Professional") and in version 5.0, which came for SPS and SPE some time after SPP 5.0, with "problemloser Austausch von Songs" between the three. So their files are assumed to be the same format. SPS lived on: a 5.2 demo, and still sold with 6.0 in 2011. Score Perfect Professional Lite is newer: it appeared in December 2008, after SPP 5.1, limited to 32 voices; there is no Lite before 5.1. No SPS, SPE or Lite file of a later version than the ones in the corpus has been tested. Source: Scoretec's news page; the SPS and SPE demos of version 4.0 are described on the SPP 1–4 page.

SPP 5 is a rewrite for Windows, in Visual Basic 6; SPP up to 4 came from the Atari ST and wrote another format, described on the SPP 1–4 file format page. SPP Lite 5.1 opens those songs and saves them in this format; part of the corpus is 116 such songs. For those, PriMus' son2emil.exe converts the originals to a readable text format, emil: a reference that named several tags below (the comparisons with son2emil). Such resaved songs also carry a few tags of their own (e0, 64).

Pictures

A picture is a whole BMP file, uncompressed, preceded by its size in 4 bytes and, before that, 8 bytes, probably its place on the page. Objektarten holds SPP's box (493 × 259 pixels, 24 bits), The Abbess a drawing of a button accordion (1376 × 1085 pixels), which is most of its 4.4 MB. They lie at the end of the staff block, before the measures block. Free texts refer to pictures as Pic#, followed by a number.

Chord list

From SPP 6.0 on, and only when the song has chord symbols: the song's chord track, at the start of the staff block, after its first record. Unlike the rest of the file it is big endian. First the chord symbols as they appear in the song, in the order they were entered, each a record of three 2-byte values, separated by ff ff:

bytesmeaning
0-1measure, from 1
2-3position in the measure, in 16ths, from 1: 9 is the third beat of a 4/4 measure
4-5chord, from 1, in the list that follows

After the last of them, without ff ff, a 2-byte count, then per chord a 2-byte length and the text: the name, a |, and the notes of the chord as MIDI note numbers. C|48,52,55 is C3 E3 G3, G7|55,59,62,65, A-|57,60,64 A minor. Then a record of a 4-byte length (little endian again) holding 00 05 and a name, probably the registered owner's.

It is probably what SPP plays for the chord symbols. 6 songs of the corpus have one, all saved by SPP 6.0. The notes carry the chord symbols themselves, so the converter does not need it.

Settings block

166 bytes after the counts, then fe ff ff ff: records separated by ff ff (the fonts' and page's settings: 11 to 13 of them, 2 to 72 bytes each, the same in every song of SPP 5.0 to 6.0). Not decoded.

Staff block

Between fe ff ff ff and the measures block. The first record: 17 or 19 bytes, ff ff or not (flags), a record of 53 bytes (in SPP 5.0: 10) with a number as text with its length first (01 31: "1"; "0,667" in Dvorak 9, "1,2" in Hirtenlied: probably a zoom), in songs with chord symbols the chord list from SPP 6.0, in some songs a text with its length (4 bytes) first: 00 05 and the name of the author (Op. 88/2, Klaus Kleinbrahm, the registered user's name in one song), the pictures, and the 10 bytes that end it. Then pages: a record of two doubles (the size of the page: 00 00 00 00 00 a0 81 40 is about 563), a zoom, the number of systems and a page number, and per system a record starting with its zoom (40 1f is 80 %): see below. Then one record per part. The size of the whole grows with the number of parts and systems (420 bytes for two parts, 1045 for Ave Verum's six). Mostly not decoded; what is known:

Measures block

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.

bytesmeaning
0-1measure number, as SPP shows it; songs can start at 0, and numbers can be skipped
204 when used, 00 when not
4-5number of note positions in the measure
11-12horizontal 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.

Measure tags

Lengths include the tag byte. The meaning holds for this measure and those after it, unless said otherwise.

taglengthmeaning
0a4? Observed: 0a 01 00 01, 0a 01 00 00, 0a 02 00 01, 0a 01 00 02, 0a 02 00 02: like 0c (the clef) a part (1 or 2), 00 and a value from 0 to 2; in Objektarten 1 and 2 (8 each) and test song d4 (2). Guess: a setting of a part's staff, such as its kind of system.
0c4clef: 0c, part, 00, clef. Written at every clef change, also back to treble
145volta length: volta number (1-based), 2 bytes number of positions under it
1f2?
3c2in the first measure, 01 to 04 (01 in 52 of the 88 songs that were looked at, 02 in 17, 04 in 18, 03 in one). Not the number of voices per staff, as once thought: a song with two parts on one staff made by hand has 01, as has a song with two staves, and 8 songs with a shared staff have 01. Neither does it change with adding, removing or combining notes, a crescendo or a system break (13 test songs made by hand, all 3c 01, 68 03 00, 71 01 00, 72 01 00, the values of an empty song); so probably a setting of the song or page
3d2volta start: volta number
3e2? (with voltas)
3f2bar line
415?
643multi-measure rest: 2 bytes, the number of measures it stands for (one Mozart bassoon part: 3, 2, 3, 3, as son2emil's P{3}, P{2}); the measure numbers skip those measures
6532-byte value: a spread or stretch, in hundredths of a percent, like the header's spread (8000 is 80 %)? The values are round numbers (3000, 4000, 5000, 11000, 25000); with a new line (66) in a fifth of the cases Tried in SPP (Bacharach, 4500 set to 6000): the widths of the measures of the first system changed a little.
663new line? Tried in SPP (Bacharach, 66 f4 00, 244, set to 66 46 00, 70, as in Vorhalte-Trick): the measures of the first system moved a little.
673key signature: 2 bytes, signed, ♯ positive, ♭ negative: fe ff is two ♭. Checked with five pieces whose keys are known; not written in C major. Changes in the middle of a song are written too (Dvořák 9: G♯ minor, A♭ major, E minor)
683? Observed: a byte and 00. The byte is a bit mask: 01, 03, 07, 0f, and 04; 24 values with the second byte, 485 times in all 110 songs, 68 03 00 in the first measure of 80 of them (68 01 00 in 22 more). Not the number of parts, and not the time signature. Tried in SPP (Bacharach, first measure, 01 set to 0f): the measures of the first system became wider, in a song with lyrics and chord symbols. Guess: a mask of what the spacing of the measures takes into account.
69, 6a3? Observed: a signed 2-byte number, little endian: 69 00 00 (13), 69 f2 ff (−14), 69 ff ff (−1), 69 02 00, 69 f7 ff (−9); 6a 00 00 (12), 6a fe ff (−2), 6a 03 00, 6a 01 00, 6a d9 ff (−39); in 8 songs, such as Dvořák 9, Beethoven 5, Bruckner, Bacharach. Tried in SPP (Bacharach, 69 2 and 6a −3 set to 40): a few pixels moved near the start of a system. Guess: a small offset of the start of a system, in layout units.
6c, 6d, 6e3? Observed: also a signed 2-byte number: 6c 00 00 (6), 6c 05 00 (3), 6c 06 00, 6c 11 00, 6c 0e 00; 6d 00 00, 6d fb ff (−5), 6d ff ff (−1); 6e 00 00, 6e 05 00, 6e 08 00; 6c in Steirische Harmonika (8) and Objektarten (2 + 2), 6d and 6e in Steirische Harmonika alone (4 each). Guess: something of the accordion systems.
713? Observed: 71 01 00 (138) or 71 00 00 (28), in all songs; 107 of the 163 are in the first measure, the others (28 of each value) later in the song. Tried in SPP (Bacharach, first measure, set to 0 and the next tag changed with it): nothing changed on the screen. Guess: a flag that is switched on or off.
723? Observed: 72 01 00 (84, all but one in the first measure) or 72 02 00 (5). Tried in SPP (72 01 set to 72 02, together with 71): nothing changed on the screen. Guess: a mode with 2 values, set once.
885?
8c3?
bc4? (near time signatures)
c85nominal length: 2 bytes, the length of a measure in the time signature, in divisions: 00 06 is 1536, 2/4
c95actual length: 2 bytes, in divisions, until the next c9. Less than c8 in an upbeat (80 01 is 384, an eighth); other than c8 in a measure of another length than its time signature
d0, d45?
e14?
e92?
ff7time signature

Time signatures

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.

codeSPP shows
01C (common time, 4/4)
02cut C (2/2)
03another cut C
04the numbers
05two numbers added: 4+0/4 (bytes 4 and 5)
06three 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.

Bar lines

Tag 3f, one byte, the bar line at the end of the measure:

codebar line at the end of the measure
00normal
01dotted
02normal, set explicitly
03double
04final (thin, thick)
05repeat end
06repeat start, of the next measure
07repeat end and start?
08repeat end and start (at a line break in Objektarten)

Checked against the Taktstriche measures of SPP's demo song Objektarten, as SPP prints them.

Clefs

The same codes in measure tag 0c and note tag e4:

codeclef
00treble
01bass
02tenor (C on the 4th line): only in bassoons and cellos (Beethoven 5, Dvořák 9)
03alto (C on the 3rd line): only in violas (Dvořák 9)
04treble, an octave down
05treble, 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)

Notes block

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).

Note

There are two forms, told apart by byte 5.

longshortmeaning
00note number, from 1
1-21-2horizontal position: byte 1 × 100 + byte 2
3300
44note number - 1
5number of tones (1 to 10)
5the short form: c7 quarter, c6 eighth, c5 16th
6the 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
7the 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-9duration: byte 8 × 100 + byte 9
106note type
117stem, 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.

Note type

3 × level + variant + 1, plus 18 hex for a rest.

levelnotecode (plain)
0whole02
1half05
2quarter08
3eighth0b
416th0e
532nd11
664th14
7128th17

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.

Stem, beam and rest

bitmeaning
03beam
04stem down
08cue note, printed small: set on the Stichnoten of Objektarten, and in the figured bass realisations of Basso continuo and Generalbass
10rest
20dotted

Checked with step-entered eighths (01 02 01 02) and 16ths (01 00 00 02).

Beams

codebeam
00continue (inside a beam), or none (quarters and longer)
01begin
02end
03a flag, no beam

Tones

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.

Note tags

Lengths include the tag byte; n is the number of tones. For the tags still unknown the rows say what is observed (the values seen, and how often), the values as pairs in base 100 where there are any, and a guess, which is no more than that. A pair is two bytes, high and low: its value is (high − 100) × 100 + low, so 63 5f is −5 and 64 04 is +4, 64 00 64 00 is 0 and 0; the offsets are probably in layout units, as the hairpins' lengths are.

taglengthmeaning
046?
10, 564?
38, 3b, 41, 48, 68, ca3?
55, ed2?
635The same record as 64 (below), with a negative first value: 63 5c 00 00 00 after a tempo in Dvořák 9, 63 61 00 00 10 in Beethoven 5. Not decoded.
645MIDI changes at this note: 64 b1 b2 b3 b4, 00 for no change. Found with test songs h0 to h3, one change per note, made in SPP: b1 the MIDI transposition in semitones (02 after "play higher 2"); b2 the MIDI instrument, from 0 (11 and 42 after changing the instrument); b3 the MIDI volume (63 = 99 and 42 = 66 after setting those; 3c, 2d and 50 in the demo songs); b4 flags: 01 start of a swing, 02 end of it (h1: note 2 starts, note 3 stops), 08 trill in 32nds (h3), and 10, which came with "play higher 2" in h3 and is on nearly every note of songs of the SPP 1–4 format saved by SPP 5.1 (64 00 00 VV 10); 04 in h0 was one of the two notes where the user set a swing. Not written to the MusicXML
6e11?
c91 + naccidentals, one byte per tone
cb2 + per chord 6 + namechord symbols: count, then per symbol 4 bytes (such as 64 00 63 46), the length of the name (1 byte), a byte (00, 61, 63: ?) and the name: "G7", "A-", "C7/9"; a minus is minor, 4 is sus4. Read as a 2-byte length, as before, the names garble when the second byte is not 00
cc3? Observed: one pair in base 100 (see below): cc 63 5f (−5, 50 times), cc 63 61 (−3), cc 63 5e (−6), cc 63 60 (−4), cc 64 08 (+8); 91 times in 15 songs, mostly Dvořák 9 (47) and Debussy (20). Stem length, tried in SPP (research/set_tag_values.py): in Debussy's Children's Corner, measures 5 and 6, the pairs were set to 64 14 (+20) and the stems and beams of the notes grew by about that much, down to the lower staff, where the original −5 and so on made them a little shorter than the standard. So the pair is a change of the stem length, in layout units, which SPP's menus do not offer (dragging a beam does it, probably). The converter does not use it.
cd2 + 2nthe notehead: byte 1 bit 02 between parentheses (SPP's "tussen haakjes"), then per tone two bytes: the shape and 64. The shapes were found by making songs from h2 with one value on each note, and looking at them in SPP (research/make_notehead_tests.py): 01 the usual head; 02 and 03 an x (two hourglass-shaped heads, which SPP draws alike); 04 a diamond; 05 a triangle; 06 a triangle pointing down; 07 to 0a other triangle halves; 0b a square; 0c a slash ("Slaggitaar", also in h2); 0d a rest sign. Values from b0 up look like characters of a font: b9 is a diamond, bf an x, c3 the usual head (the three of the demo songs, bf on 158 notes), b0 a note with a flag, b5 an open triangle, c0 a circled x, c8 an ornament; 00 the usual head, 50 a b-like sign, 64 a zigzag. The converter writes the usual shapes: x, diamond, triangle, inverted triangle, square, slash, and the parentheses
ce7arpeggio: byte 1 00 plain, 01 with an arrow up, 02 with an arrow down (Objektarten's Arpeggio measure)
d01? (read as 8 bytes, it swallowed the slur stop after it in Mozart's KV 281)
d116hairpin, on the note it starts at: byte 1 01 crescendo, 02 diminuendo; byte 2 how many measures later it ends, byte 3 the number of the end note in that measure (from 1, as in the slur start d9): in test songs made by hand and shown in SPP (research/test_songs/maarten/c1-c5) a crescendo from the second note to the third reads 01 00 03, to the fourth 01 00 04, a diminuendo to the third 02 00 03, one that ends on the first note of the next measure 01 01 01, one on the first note of the second measure to its fourth 01 00 04; SPP draws each of them so. Byte 4 was 05 in all of them; bytes 8-9, 10-11, 12-13 and 14-15 (base 100 around 100) were 64 00, 64 2a, 64 08 and 64 2a in all of them: offset, y, length and y of the drawing, which the user can change. In songs that SPP Lite 5.1 saved from the SPP 1–4 format bytes 2-3 are 00 (the end was not computed), the sign of bytes 12-13 then says whether the tag is on the start (positive) or the end note (negative), and the end follows from the layout as in the SPP 1–4 format (see Hairpins there). The converter reads the end from bytes 2-3 and leaves the other hairpins out.
d21 + 2 per tone(the length follows the number of tones: 3 bytes on a single note, 5 on a chord of two; found in Dvořák 9) comes before the ornaments (e5) of a note, as often as son2emil writes ornaments (35 of 36 songs): two MIDI pitches near the note's own, on a B♭4 (70) C5 and A4 (72, 69), probably the ornament's upper and lower auxiliary notes, for playback
d33? Observed: d3 63 63 (−1, 112 times), d3 64 01 (+1, 48), d3 64 02 (+2, 42): one pair; 202 times in 4 songs, 176 of them in Debussy's Children's Corner, 12 each in Objektarten 1 and 2. A sideways shift, tried in SPP (Mendelssohn's Lass, o Herr, mich Hilfe finden, measure 5, set to 64 05, +5): the note and its stem moved to the right. Which differs from dc is not known (d3 is mostly 0 to +2, dc −9 to +9). The converter does not use it.
d411? Observed: d4 NN 00 and 4 pairs in base 100: d4 01 00 64 00 63 5a 64 1e 64 14 (0, −10, +30, +20), d4 02 00 63 5e 63 5a 64 1e 64 14, d4 03 00 63 63 64 25 64 14 64 0e, d4 04 00 64 28 63 54 65 1f 64 3c; NN counts 1, 2, 3 ... in a song: 12 each in Objektarten 1 and 2, 6 in Steirische Harmonika. A line, tried in SPP (Vorhalte-Trick, measure 3: the pointer line from "Notenkopftool" to a picture of the toolbar): the 4 pairs are the x and y of the start and the x and y of the end, relative to the note (the x of the start, the x of the end and the y of the end were moved, and the line followed). NN numbers the lines of the song. The converter does not use it.
d529chord diagram (Griffbild): frets, then the name padded with spaces (Objektarten's Griffbilder measures); not decoded further
d61 + 2nties, 2 bytes per tone: the tie, then 64. Usually towards the same pitch in the next note; 223 times in the corpus towards another pitch (Mozart KV 281's left hand: each chord a tie start, none a stop). SPP draws nothing for those: no tie, no slur (checked by loading the song in SPP)
d923, or 41 when byte 2 is not 00; 4 more or less for each point more or less than 4slur start. Byte 1: the number of curve points (4, once 3); byte 2: how many measures later it ends; byte 3: the number of the end note in that measure, from 1 (rests count). In the 391 slurs of two songs that SPP 5.1 saved from SPP 1–4 files, byte 2 and 3 name the note that carries the matching da, 100%, in slurs of up to 4 measures. Then the curve, 4 points of 4 bytes with the first bytes of the tag before them
da7, or 24 when byte 1 is not 00slur stop
db2 + per verse 10 + textlyrics: number of verses, then per verse 10 bytes (the text length in byte 8) and the text
dc3? Observed: one pair: dc 63 60 (−4, 27 times), dc 63 5c (−8, 26), dc 64 04 (+4, 24), dc 63 5e (−6, 24), dc 64 09 (+9, 23), and 33 more values; 328 times in 27 songs, most in The Shadow of Your Smile (56), Dvořák 9 (38) and Debussy (36). A sideways shift, tried in SPP (Mozart KV 281, measure 4, set to 64 14, +20: the first note, with its stem and flag, moved right by about as many pixels); in layout units. The converter does not use it.
dd5Two base-100 pairs: dd 64 00 63 62, dd 64 00 64 02 (13 times, only Beethoven 5; the first pair 0, the second −2, 2, 4, 8, 12, 18). A shift of some kind; not tried in SPP. The length is certain: the tags after it (e0, e5) are read correctly.
de2number of dots, when more than one: de 02 with a double-dotted whole (5376), de 03 with a triple-dotted one (5760), in Song31
e03a tempo, from this note on, in base 100 (01 32 is 150, 00 4d is 77: moved in SPP's tempo field in test song h0; the demo songs have 00 5a 90, 01 14 120, 01 50 180 and so on); 00 00 for no change, which is on nearly every note of songs of the SPP 1–4 format saved by SPP 5.1. SPP draws nothing for it (Dvořák 9 has values of 15 to 60 that no tempo mark shows), so the converter writes it as a sound tempo only The header's tempo (the counts) is written as a sound tempo too, in the first measure.
e14 for a middle note, 8 for the first, 10 for the lasta note of an n-tuplet (Objektarten's 9-tuplet): byte 1 01 for the first note, 00 for the middle ones, 02 for the last; bytes 2-3 the note's duration, base 100, as in the header. The first and the last note carry two base-100 pairs more (64 00 63 5e, 64 0c 63 61, probably where the bracket ends), the last note also 2 bytes: 09 01, 09 the tuplet number; so the tag is 8 bytes on the first note and 10 on the last, which used to leave pairs to be read as tags. The durations are irregular (288, 96, 288, 70, 128, 128, 279, 279, 69) and add up to 1625, where the measure's actual length is 1649
e23ottava, on every note under the line; the notes are stored as they sound
e44clef change before this note: byte 1 the clef
e52 + 5 per itemmarks above or below the note: count, then 5 bytes each, the first the mark
e64tremolo: byte 1 00 on one note, 01 between two notes (both are marked); byte 3 the number of strokes (Objektarten's Tremolo measures; Dvořák's strings)
e92the notehead, hidden for 06 (SPP's "Verbergen", test song h2: the note is drawn in a yellow box on screen); 01 (Objektarten) and 04 (Telemann) are other choices of the menu, not tried. The converter writes 06 as <notehead>none</notehead>
ea3grace note (appoggiatura)
ec5? Observed: 2 pairs, mostly equal: ec 63 5f 63 5f (−5, −5; 7 times), ec 63 62 63 62 (−2, −2), ec 63 61 63 61, ec 64 3f 64 41 (+63, +65), ec 64 00 64 00; 127 times in 15 songs (Debussy 74, Mendelssohn's Frühlingslied 17, Mozart KV 281 10). The beam, tried in SPP (Mozart's KV 281, measures 1 and 2, the first pair set to 64 14, +20): in each group of beamed notes the beam was drawn sloping, its left end 20 units lower, with the stems longer to reach it. So the two pairs are the heights of the beam at its first and at its last note, as a change of the standard; two equal values (as 63 5f 63 5f) move the beam as a whole. The tag is on the first note of the beam. The converter does not use it.
ee10glissando, on the note it ends at; byte 1 03 or 04, perhaps the line (Objektarten's Glissando measures)
ef2? Observed: ef 02 (37) or ef 04 (36), in 12 songs, such as the two Mendelssohn choir songs and Debussy. Tried in SPP (Bacharach, measure 2, the two ef of the left hand set to 00, 08, 10 or ff): the note heads that were drawn to the other side of the stem, as in a second, went back to their place, and 02 and 04 each draw a head of a chord on the one or the other side. Guess: on which side of the stem the head is drawn. The converter does not use it.
f15 + bytes 4-5a triplet's bracket?
f26 + bytes 4-5a colour: byte 1 01, byte 2 what it colours (01 the notehead, 06 the stem, 63 the whole note), byte 3 00, bytes 4-5 the length of the text that follows, which is the colour as a decimal number, blue × 65536 + green × 256 + red, as Visual Basic has it: 31 30 35 32 39 32 36 is "1052926", red (#FE1010), on the stem of one note of the test song h0, SPP draws a red stem; "16526123" is blue (#2B2BFC) on a notehead, drawn so; the demo songs have "0" (black) on every note of the Arbeitsblatt and greys such as "5723991" (#575757) in Bacharach. The converter writes the stem and notehead colours. The length was once taken as 5 + the text, one short
f324Observed: f3 01 1e 01 64 00 63 60 64 00 64 00 64 00 64 00 64 0c 64 3c 00 00 00 00: 01, a number, a byte, 8 base-100 pairs and 4 bytes 00 (9 times in Objektarten 2, 4 and 4 alike). Guess: the shape of one of Objektarten's special beams. The length is certain (the next tag starts right after). Layout.
f43? Observed: always f4 00 4b, 1089 times, in one song, Czerny's Etude op. 740 (4b is 75). Guess: a value per note, such as the velocity.
fa3? Observed: fa 00 01 and fa 00 02, 16 times each, only in Objektarten 1 and 2. A feathered beam, tried in SPP (Objektarten 1, measure 24, "Accelerando- und Ritardando-Balken", on all 16 notes: eight with 01, eight with 02): swapping the two values swapped the shapes of the two beams, 00 drew both as ordinary beams of 3 lines. So 01 and 02 are the two kinds, accelerando and ritardando (the beams spreading to the one side or the other). The converter does not use it. The reader does not know the tag, so it ends there for the rest of the note (finding "unknown note tag").

Accidentals

codeaccidental
00none
01𝄫
02♭
03♮
04♯
05𝄪

Ties

The first byte per tone of tag d6:

codetie
01start
02stop
03continue (stop and start)
+04curved under
+10curved over

Ottavas

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.

codesignMusicXML octave-shift
01, 028, 8va, abovedown, 8
03, 0415, 15va, abovedown, 15
05, 06-8, -8va, belowup, 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, belowup, 15

Marks

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:

codemarkMusicXML
52, 53, 54, 55, 56, 57, 58, 59ppp, pp, p, mp, mf, f, ff, fffdynamics: ppp, pp, p, mp, mf, f, ff, fff
5a, 5b, 5c, 5d, 5esf, fz, sfz, ffz, fpdynamics: sf, fz, sfz, other-dynamics ffz, fp
6cstaccatoarticulations: staccato
6dtenutoarticulations: tenuto
6ea small wedgearticulations: spiccato
6faccent (>); once taken for a diminuendoarticulations: accent
70V (an upside-down marcato?)articulations: strong-accent, type="down"
71marcato (Λ)articulations: strong-accent
72wedgearticulations: staccatissimo
73down-bowtechnical: down-bow
74up-bowtechnical: up-bow
75harmonic (o)technical: harmonic
48, 49, 4a, 4b, 4c, 4d, 4efingerings 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):

codemarkMusicXML
48, 49, 4a, 4b, 4cfingerings 1 to 5: as many of each as son2emil writes, in every songtechnical: fingering
62inverted mordent (Pralltriller, son2emil's t2): as many as son2emil writes in every MEL song (7, 10, 8, 26 …)ornaments: inverted-mordent
76, 77pedal 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 handdirection: pedal (start, stop)
7acoda (S{cod}), in 6 songsdirection: coda
7bsegno (S{seg})direction: segno
7dD.S. (S{DS})direction: words D.S.
7e? 144 times in Liebestraum, among 76 and 77; son2emil writes nothing for itnone 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:

codeSPP draws
00, 01, 02a clef sign by the note: treble, bass, a C clef (the clefs of e4?)
12a flat sign above the note (tried in an old song: replacing a staccato of Mozart's CLAR1DL4 in SPP Lite 5.1)
13a natural sign above the note (in the Czerny test in one measure, in another nothing)
29a small treble clef sign
35, 96a short stroke before the note, like a small grace stroke
88, 90a short vertical stroke above the note (old song; 90 drew nothing in the Czerny test)
3fa small flag-like hook above the note
4d, 4ethe fingerings 6 and 7 (above the note, like 48 to 4c for 1 to 5)
65a wavy line with a hook down at its start
66a wavy line with a small hook at its start
67a wavy line with a hook up at its end
68a wavy line with a vertical stroke through it
6ba small wavy line below the note (old song)
7ea small rest-like zigzag below the note (old song; 144 times in Liebestraum)
84a small bass clef sign above the note
97a small arc above the note
98a plus sign above the note (a stopped note)
05, 28, 2f, 36, 90nothing 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.

Texts and part groups

After the notes, 7 records of the same shape, a 4-byte length and its data.

The first holds the free texts, as records separated by ff ff, each a 15-byte header and the text:

bytesmeaning
100: tied to a measure; 01: tied to the page (titles, page texts)
2-3the measure, counted from 1, as two bytes in base 100: hundreds, then the rest (byte 2 × 100 + byte 3; Toccata's Recitativo, measure 129, is 01 1d). Read as one big-endian number, the texts after measure 99 land beyond the end of the song
4the part
6-9the position; bytes 8-9 the height, base 100 around 100: 63 4a is above the staff
10style: 58 a boxed rehearsal mark
11-12the font, a number into the fonts of the header?
13-14the length of the text, big endian

Checked against Objektarten as SPP prints it: the rehearsal marks A, B, B1, B2, C land in measures 31, 35, 37, 39 and 40, the captions over the measures they name. Texts starting with Pic# are pictures, with Akk# accordion registers; Pic#2 inside a text is a picture in it, such as a note. Some longer texts have a header that does not fit this layout. The converter keeps the texts tied to a measure (first byte 00) with something in them, except the Pic# and Akk# ones; the part is byte 4 (the first part if 0); a text is above the staff when its height byte (8) is below 100, or its style is 58. It does not convert the texts tied to the page (titles, page texts) and says so in the log for texts outside the song.

Breath marks (Objektarten's Atemzeichen measures) are symbols among the free texts: Pic#1102G5Z6, Pic#1104G5Z4 and the like, in the measures of the breath marks. Pic#1104 also occurs in two figured-bass songs, Pic#1101 in Mendelssohn's Hirtenlied; the numbers and the rest of these names are not decoded.

Part groups

The other six records are lists of part ranges: pairs of a first and a last part number. 01 02 06 06 is parts 1 to 2, and part 6.

listmeaning
1?
2brackets
3braces (the parts of one instrument, such as a piano)
4-5empty in every song
6the third list of the SPP 1–4 format, unchanged: it is equal in all 96 songs of that format that have these lists (the SPP 1.4 song's settings are not read), and it is not empty in 92 of them. It draws nothing; son2emil writes it as the ~ groups of Set grouping, in numbers of its own. Meaning unknown

Checked by loading copies of a two-staff song with one list set in SPP: list 2 draws a bracket, list 3 a brace; the others drew nothing visible. SPP's default song has a bracket around its two staves. Parts drawn on one staff are not in these lists.

Part names

After the part groups: the guitar tuning, 34 39 3e 43 47 4c (MIDI notes E A D G B E), then per part two strings with a 4-byte length: its name and its abbreviation (Ave Verum: Sopran, Alt, Tenor, Baß, Orgel, Orgel). The tuning is the same in every file so far; it is probably what a tablature staff uses.

Tail

After the part names comes the mixer. Not every file has it right there: songs with marker names have those first, each a 4-byte length and its text ("SPP 4.0 Marker 1", "Choral", "Intro"), and the mixer follows the last one without the 2 bytes in front of its master volume. The converter looks for the mixer in the same place for every file, and when that gives values above 127 it follows the chain of marker names and reads it after them. What lies between the part names and the markers is not decoded.

lengthmeaning
200 00
1the master volume, 0 to 127 (7f by default)
100
16 × 5one record per MIDI channel (part n plays on channel n, up to 16), see below

A channel record:

bytesmeaning
0the fader, the volume: 0 to 127 (6e or 64 by default)
100, never seen otherwise
2a dial, 0 to 127 (0 by default): the yellow one, 0 to 10
3the pan, 40 in the middle, 7f at the far right of the green dial (−5 to +5)
4another dial, 0 to 127 (0 by default): the red one, 0 to 10

Found with test songs g0 to g9, one control moved at a time:

songcontrol movedbyte
g1pan of channel 1 to the far right40 to 7f
g2the yellow dial of channel 1 to 9byte 2: 73 (115)
g3the red dial of channel 1 to 6 or 7byte 4: 66 (102, 8 on a scale of 127 to 10: the dial was read by eye)
g4fader of channel 1 from 110 to 301e
g5all four controls of channel 16volume 52 (34), byte 2 2b, pan 54, byte 4 1f
g6the master fader from 127 to 2418, the byte before the records
g7the MIDI program of channel 2 to 94not here: the program of the part's record in the staff block (5d)
g8, g9master pan to 66, master chorus to 55 (and master hall to 44)no change in the file

The yellow and red dials are probably the reverb (Hall) and the chorus of the SPP 1–4 format's mixer, in that order, but which is which is not known. The converter writes the volume and pan of part n into the MusicXML <volume> and <pan>.

The marker names come before the mixer (see above). Their positions are not decoded.