SMUS — the music score format
SMUS — Simple Musical Score
Section titled “SMUS — Simple Musical Score”War in Middle Earth’s music is 22 .smus files in EA IFF 85 “SMUS IFF
Simple Musical Score” (Jerry Morrison, Electronic Arts, February 1987) — a
published standard, not a bespoke format. Each score references its
instruments by name; those are SampledSound
.instr files.
Divisions shorter than a 16th note are silently played as rests. That is not a decoder bug and not a data bug — the Sonix player’s own duration table maps 32nd, 64th and 128th notes to
$FF, which takes the silence path. A faithful playback engine has to reproduce it.
Container
Section titled “Container”FORM <size> SMUS SHDR <8 bytes> score header (required) NAME <variable> score name (optional) INS1 <12+> instrument reference (zero or more) TRAK <variable> track event stream (one or more)SHDR — score header (8 bytes)
Section titled “SHDR — score header (8 bytes)”+0 u16 tempo 128ths of a quarter note per minute+2 u8 volume master volume, 0–127+3 u8 ctTrack number of tracksDivide tempo by 128 for BPM: Aragorn.smus stores 0x397C (14,716) =
115 BPM; Title.smus stores 0x2FA0 (12,192) = 95.25 BPM.
INS1 — instrument reference
Section titled “INS1 — instrument reference”+0 u8 register instrument register index (0, 1, 2 …)+1 u8 type instrument type code+2 u8 data1+3 u8 data2+4 varies name null-terminated filename stem, e.g. "Piano"The register field is what TRAK’s instrument-select events refer to; the
name field matches a .instr file on disk.
Names can be truncated, and that’s normal. The name field uses
chunkSize − 4 bytes; a name longer than the space available is simply cut
short — "Bass1Shorter" appears as "Bass1Shor" in Aragorn.smus. Bytes
after a null terminator are garbage padding. This is standard SMUS behaviour,
not corruption.
TRAK — track event stream
Section titled “TRAK — track event stream”A flat sequence of 2-byte events: a type code, then a data byte.
sID |
Event | Data byte means |
|---|---|---|
| 0–127 | Note | The sID itself is the MIDI pitch; data is the duration field below |
| 128 | Rest | Duration field below |
| 129 | Instrument | Select instrument register |
| 130 | Time signature | Bits 7–3 = numerator − 1, bits 2–0 = log2 denominator |
| 131 | Key signature | Key signature code |
| 132 | Dynamic | Volume / velocity, 0–127 |
| 133 | MIDI channel | Channel assignment |
| 134 | MIDI preset | Program change |
| 135 | Clef | Clef type |
| 136 | Tempo | Tempo change, quarter notes per minute |
The note/rest data byte
Section titled “The note/rest data byte” 7 6 5-4 3 2-0+------+------+------+------+------+| rest | tie | grp | dot | div |+------+------+------+------+------+- rest (bit 7) — silence for the given duration
- tie (bit 6) — the note sustains into the next event
- grp (bits 5–4) — voice group select; when non-zero, Sonix skips the event
- dot (bit 3) — dotted
- div (bits 2–0) —
0whole,1half,2quarter,3eighth,416th,532nd,664th,7128th
Duration in quarter-note units:
base = 4 / (1 << division)if dot: base *= 1.5if triplet: base *= 2/3if quintuplet: base *= 4/5if septuplet: base *= 4/7The Sonix duration table
Section titled “The Sonix duration table”Confirmed by reading the player’s own lookup table (LAB_01B0 in
Sonix.code). Each entry is a CIA tick count at 8 ticks per quarter note —
exactly 8× the quarter-note units above:
| Index (div) | Division | Value | Quarter notes |
|---|---|---|---|
| 0 | whole | $20 (32) |
4.0 |
| 1 | half | $10 (16) |
2.0 |
| 2 | quarter | $08 (8) |
1.0 |
| 3 | eighth | $04 (4) |
0.5 |
| 4 | 16th | $02 (2) |
0.25 |
| 5–7 | 32nd–128th | $FF |
rest — unsupported |
That last row is the hardware limitation in the callout above: three of the eight encodable divisions have no playable duration on this player at all.
Playback
Section titled “Playback”The reimplementation interprets SMUS directly through a Web Audio renderer rather than pre-converting the scores to another tracker format — the build step now emits only a manifest, and no audio files are generated ahead of time.
Where the full evidence lives
Section titled “Where the full evidence lives”docs/formats/smus.md in the main repository (not part of this site), with
WIME’s own playback notes in docs/wime/amiga/music-playback.md and the
known decoder issues in docs/wime/amiga/smus-decoder-issues.md.