CosmOS lets every voice go when a program stops
A gate is a register on the sound device and only a program can drop one. A program that has stopped cannot: it is gone. So a note left held sustained until something else said otherwise, and nothing else did - one program could leave the machine sounding for as long as it ran, with nothing the person at it could do. The shell already puts back the Stack, the vectors, the drive, the working directory and the screen. This is the same list and the same argument, and the fault path calls it too, for the stronger version of the argument: a program that CRASHED is exactly the one that cannot tidy up after itself, and a machine that will not stop humming is a poor place to read an error message. It does not make the device silent at once and does not pretend to. Dropping a gate RELEASES a note rather than stopping it, so the patch's release still runs. A bounded tail rather than an endless one is the part the system can be responsible for without knowing what instrument the program had built. Hum exits while holding a note; Pause makes no sound and takes a couple of million cycles, because the machine stops the moment the shell runs out of input and a note quietened at that instant leaves no samples behind to say whether it was. They are on a disk of their own so that a fixture does not move the ten recordings that quote cosmos.img's listing. THE CHECK CAUGHT ITSELF PASSING WRONGLY FIRST. Pause was missing from the disk, the machine halted immediately, and the window that should have held the tail was past the end of a render a twentieth of a second long - an empty window's peak is nought, which is indistinguishable from silence. So the sample count is asserted before anything is read from it. Verified with break.sh: without the call the note is still ringing at 9869. 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
7f96499438
commit
f9b08cf7f9
@@ -702,6 +702,59 @@ QUIETER="$ALONE0"
|
||||
&& result ok "and then both at once" "peak $TOGETHER against $ALONE0 and $ALONE1 alone" \
|
||||
|| result no "and then both at once" "peak $TOGETHER, which is not above either of $ALONE0 and $ALONE1"
|
||||
|
||||
# ---- The system quietens a note the program that made it cannot ----
|
||||
#
|
||||
# A gate is a register on the sound device, and only a program can drop one. A program that
|
||||
# has stopped cannot: it is gone. So a note left held sustains until something else says
|
||||
# otherwise, and nothing else did - which means one program could leave the machine sounding
|
||||
# for as long as it ran, with no way for the person at it to stop it.
|
||||
#
|
||||
# CosmOS now lets every voice go when a program hands the machine back, the same way it puts
|
||||
# the screen and the drive and the vectors back, and from the fault path too - because a
|
||||
# program that CRASHED is exactly the one that cannot tidy up after itself.
|
||||
#
|
||||
# Hum starts a note whose envelope sustains at full and exits while holding it. Pause makes no
|
||||
# sound and takes a couple of million cycles, and it is there because the machine stops the
|
||||
# moment the shell runs out of input: a note quietened at that instant would leave no samples
|
||||
# behind to say whether it had been.
|
||||
#
|
||||
# ITS OWN DISK, so that a fixture run by one check does not move the ten recorded tests that
|
||||
# quote cosmos.img's directory listing.
|
||||
if [ ! -f "$ROOT/Tests/build/disks/quiet.img" ]; then
|
||||
result no "the system quietens what a program left sounding" "quiet.img is missing; run Tests/makedisks.sh"
|
||||
else
|
||||
"$ASM" -I "$ROOT/Programs/Libraries" -I "$ROOT/Programs/CosmOS/Source" \
|
||||
-o "$BUILD/cosmos.bin" "$ROOT/Programs/CosmOS/Source/cosmos.asm" >/dev/null 2>&1
|
||||
printf 'Hum\nPause\nexit\n' > "$BUILD/quiet.in"
|
||||
timeout 60 "$EMU" --fast --cycles 20000000 --sound "$BUILD/quiet.raw" \
|
||||
--disk "$ROOT/Tests/build/disks/quiet.img" "$BUILD/cosmos.bin" \
|
||||
< "$BUILD/quiet.in" > "$BUILD/quiet.out" 2>&1
|
||||
|
||||
# ---- PROOF THAT ANYTHING WAS MEASURED AT ALL ----
|
||||
#
|
||||
# This check reads a window near the end of the render, and a window past the end of the
|
||||
# samples is empty, and an empty window's peak is nought - which is indistinguishable from
|
||||
# silence and passes. It happened: Pause was missing from the disk, the machine halted the
|
||||
# moment the shell ran out of input, and the check reported a quietened note on a render
|
||||
# a twentieth of a second long. So the length is asserted before anything is read from it.
|
||||
SAMPLES="$(measure quiet count)"
|
||||
[ "$SAMPLES" -gt 150000 ] \
|
||||
|| result no "the quieting check measured a real run" "only $SAMPLES samples, so the windows below are empty"
|
||||
|
||||
# The note has to have been made, or silence afterwards proves nothing at all. This is the
|
||||
# half that would let the check pass on a machine where the sound device did not work.
|
||||
STARTED="$(measure quiet peak 0 40000)"
|
||||
[ "$STARTED" -gt 1000 ] \
|
||||
&& result ok "a program can leave a note sounding" "peak $STARTED while it held one" \
|
||||
|| result no "a program can leave a note sounding" "peak $STARTED, so nothing sounded and the rest proves nothing"
|
||||
|
||||
# And by the end there is nothing, though the program that started it never let go.
|
||||
LEFT="$(measure quiet peak 100000 0)"
|
||||
[ "$LEFT" -lt 200 ] \
|
||||
&& result ok "the system quietens what a program left sounding" "peak $LEFT after it handed back" \
|
||||
|| result no "the system quietens what a program left sounding" "peak $LEFT, so it is still ringing"
|
||||
fi
|
||||
|
||||
echo
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
echo "All $PASS sound checks passed."
|
||||
|
||||
Reference in New Issue
Block a user