TuneC: a written tune becomes the bytes the player reads
The compiler, and the last thing the ladder was waiting for. A tune names
its instruments, writes sequences of notes and durations, and gives each
voice an order list of sequence names - which is where repetition comes
from, since a phrase played four times is written once and named four
times.
#Tick 0d125000
#Patch Oboe oboe.patch
#Voice 0d0 Oboe
#Sequence Verse
0d64 0d4 0d67 0d4 0d72 0d8
#Order 0d0
Verse Verse Ending
"#" is a directive and ";" is a comment, exactly as in SplitBit assembly
and in the shell's scripts, and numbers are written the way the assembler
writes them. One rule across the machine rather than a third dialect -
and the rule earned itself immediately: the first tune I wrote said
"#Voice 0" and was refused, correctly, for a bare number.
WHAT IT REFUSES IS EVERYTHING THE PLAYER CANNOT NOTICE. The machine has
no names, so it cannot say a sequence does not exist. It has no lengths,
so it cannot say the voices will come apart four bars after the mistake.
A duration of nought is counted down to 255 and held, which sounds like a
hang rather than an error. And by the time a tune is loaded, "no starting
instrument" and "instrument nought" are the same byte - so the user's
ruling, that a voice with a part and no instrument is an error, can only
be kept here.
SoundPatch gains --blob, writing the same table as raw bytes. It stays
the only thing that reads soundThing's JSON: a second program parsing
that format is a second opinion about what a patch means, and the seam
between two opinions is where the LFO bug lived for a fortnight. Patches
are found beside the tune and then on a -I path, the way an include is.
THE TEST IS THAT TWO IMPLEMENTATIONS AGREE. maketune.py lays the fixture
out by hand and TuneC compiles a written source, and the suite checks
they match byte for byte - the discipline SplitDisk and sbfs.asm are held
to, for the same reason: either alone is only self-consistent. The
fixture predates the compiler, so this is also TuneC checked against
something written before it existed. Four more checks cover the four
refusals.
Also: the SoundPatch binary was tracked, alone among the six tools, and
.gitignore lists every other one. Untracked, and TuneC added beside it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
bfc46d982e
commit
2808688fa1
@@ -713,6 +713,29 @@ printf 'system /System/Boot/cosmos.bin\n' > "$WORK/lonely.cfg"
|
||||
# directory listing that ten recorded tests quote.
|
||||
python3 "$ROOT/Tests/maketune.py" "$WORK/two.tune" >/dev/null
|
||||
"$TOOL" put "$DISKS/quiet.img" "$WORK/two.tune" two.tune >/dev/null
|
||||
|
||||
# ---- And the same tune, written down and compiled ----
|
||||
#
|
||||
# TWO IMPLEMENTATIONS OF ONE FORMAT, which is the discipline SplitDisk and sbfs.asm are held
|
||||
# to: maketune.py lays the bytes out by hand and TuneC compiles a written source, and the
|
||||
# suite checks that they agree byte for byte. Either one alone would only be self-consistent.
|
||||
#
|
||||
# The patches are SoundPatch's, in the raw form TuneC embeds. Two blobs differing in one
|
||||
# parameter, the octave, so the same note number sounds an octave apart.
|
||||
"$ROOT/SoundPatch" --blob "$ROOT/Programs/Sounds/Oboe.json" Low "$WORK/low.patch" >/dev/null
|
||||
python3 - "$WORK/low.patch" "$WORK/high.patch" <<'FIXTURE'
|
||||
# The fixture patches are written here rather than converted, because what they have to be is
|
||||
# two patches identical but for the octave - which is a fact about the test and not about any
|
||||
# instrument anybody designed.
|
||||
import sys
|
||||
def blob(octave):
|
||||
pairs = [(0x00, 2), (0x01, 0xFF), (0x05, 1), (0x20, 0),
|
||||
(0x21, 0), (0x22, 0xFF), (0x23, 5), (0x04, octave)]
|
||||
return bytes([len(pairs)]) + b"".join(bytes(p) for p in pairs)
|
||||
open(sys.argv[1], "wb").write(blob(128))
|
||||
open(sys.argv[2], "wb").write(blob(129))
|
||||
FIXTURE
|
||||
"$ROOT/TuneC" -I "$WORK" "$ROOT/Programs/Tunes/two.tune.txt" "$WORK/compiled.tune" >/dev/null
|
||||
"$ROOT/Assembler" -I "$ROOT/Programs/Sounds" -I "$ROOT/Programs/Libraries" \
|
||||
-I "$ROOT/Programs/CosmOS/Source" \
|
||||
"$ROOT/Programs/CosmOS/Apps/Play.asm" -o "$WORK/Play.sbx" >/dev/null
|
||||
|
||||
Reference in New Issue
Block a user