D19: the S3000 header is 192 bytes, and an AKAI payload must be the file its entry placed - #36
Merged
Merged
Conversation
This was referenced Aug 22, 2026
… file Closes #23, whose bug did not reproduce: all 96 payloads disagreeing with their directory entry were already refused. Ruling out the S3000 false-positive case found the defect underneath -- 13 451 of 56 490 AKAI samples carry a 192-byte header and were read at 150, putting 42 bytes of header into the audio and dropping the last 21 frames. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bmxcode
force-pushed
the
d19-akai-payload-check
branch
from
August 22, 2026 01:25
0bede50 to
b12cec5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #23. Opens #35.
What #23 asked for, and why it is not what this delivers
#23 says an AKAI sample payload whose header disagrees with its directory entry is extracted silently, as a WAV that opens, plays, and is somebody else's audio. It names nine files on
AMG - Kickin' Lunatic Beats 2 AKAI CD1, proposes four tests, and asks for a sweep across the collection before deciding what a failure should do.The sweep says it does not reproduce. Across all 44 AKAI discs and 56 490 sample entries, 96 payloads disagree with their entry and all 96 were already being refused, the nine named files included. Nothing was extracted silently and nothing ever had been:
_looks_like_headerhas tested the id, the valid byte and the name's decodability since D3, andparsehas tested the rate. Three and a half of the four proposed tests were already there.The 96 are also, exactly, the 96 skips the README already reported — 92 "do not begin with an AKAI sample header" plus four "implausible sample rates". Not a near-miss: the same files. The counts were suspiciously close because they were the same count.
What the issue did have was the false-positive case it told us to rule out first — the S3000 192-byte header variant exists, and a check keyed to 150 that fires on every S3000 disc is what to rule out first. Ruling it out is what found the defect underneath, and that is the headline.
The headline: 13 451 samples were read 42 bytes early
The S3000 family writes a 192-byte header where the S1000 family writes 150, and every sample was read at 150.
That does not fail. The frame count comes out right, the WAV opens, the length is within 0.1 %, and the payload-versus-output check the README ran compared the output against the same wrong offset it was written from. What shipped was a WAV beginning with 42 bytes of header read as PCM — a burst of roughly ±20 000 lasting 0.24 ms, an audible click in place of the attack — missing the last 21 frames of the sound, with every loop point 21 frames out of alignment.
13 451 of the 56 490 AKAI samples, on nine discs:
AKAI.S3000.Sound.Library.1–7(4 455, 3 086, 1 990, 1 010, 601, 168, 218),East Connexion Piano(730) andAMG - Now CD-Rom for (AKAI)(1 193). Anyone who has extracted those discs should do it again.Three structures agree on it and none knows about the others:
.s3srather than.s1s. The split is perfect: 13 451 high-bit files at 192, 42 989 low-bit files at 150, no disc mixing the two rules, no exception.words × 2 + header_lenon 56 430 of 56 430 payloads readable at all. The 60 that fail that identity are the damaged ones, and every one of them fails an identity test too.Library.2'sNPF E0, offsets 150–170 are zero and 171–191 are0a ff ff 22 a8 00 aa ff ff …, the same shape on every sample of the disc, which audio is not. Waveform starts at 192.HEADER_LEN_S3000 = 192was declared insample/akai.pyand read by nothing. The format doc said S3000 discs may use a 192-byte variant and to branch on the id and valid bytes — wrong twice: the variant is not conditional, and0x80appears on 42 989 samples at 150 and 13 410 at 192.31 healthy samples were being thrown away for a bit
Of the 96 refusals, 31 fail on the valid byte alone:
0x81on 29 samples ofLibrary.2,0x9con two ofLibrary.1. Correct id, name matching the directory exactly, a normal 44 100 or 22 050, and a word count the declared size agrees with at 192.0x80is a flag inside a byte and was being tested as the whole byte — 29 consecutive1015 E.PF,1051 VL+PIZand1054CHO HARPentries that are plainly a library's own multisamples.What moved
The stereo joins move because 31 more samples means twelve more
-L/-Rpairs with both halves present. E-mu (14 738), ISO 9660 (11 601) and Roland (6 392) do not move by one, and neither does anything in the directory walk:_AKAIand_AKAI_FIRST_PARTITIONintests/test_discs.py— volumes, files, noted volumes, declared and present partitions — are untouched on all nine pinned discs, which is the control on this being a payload change and not a filesystem one.Every S3000 disc's audio changes. That is the point and it is the risk.
The four tests, and which of them earn their place
Over the 65 refusals that remain once the flag is read as a flag:
!= 30x80bit!=the entry'sThe name comparison — the one thing #23 was actually about — detects nothing the other three miss. Every payload whose name disagrees also has a wrong id and a cleared valid flag, because on these images the displacement lands mid-audio and mid-audio does not look like a header.
It ships anyway, and the argument is not a count. The other three ask whether the payload is a sample; only this one asks whether it is this sample, which is the failure class #23 named and the one #25 will raise. It costs one string comparison. What this PR does not claim is that it has been shown to work on a disc: it is exercised synthetically alone, against a fixture where
ALPHA's entry points at a complete valid header forBETA, and the test docstring, the format doc anddocs/README.md's "What is not done" all say so.The failures cluster, which is what says the check is right
60 of 65 are a run to the end of one volume. The other 34 AKAI discs have none at all,
Advance Orchestra's 2 236 samples included.Best Service - Alpha Dance IIAC.DRUMLOOPS, last 21 of 22Best Service - Alpha Dance IATTACK BANK2, last 15 of 18Kickin' Lunatic Beats 2 CD113-TRACK 06, last 9 of 20AKAI.S3000.Sound.Library.5SURDO, last 7 of 13AKAI.S3000.Sound.Library.13084 B.BEAT6last 3 of 8; one rateAMG - Global Trance Mission 2AMBIENT PAD2, last 3 of 6AKAI.S3000.Sound.Library.2AKAI.S3000.Sound.Library.3VOLUME 001, its only fileAudio Factory - Classical Wild TakesVOLUME 002, last of 2AMG - Loop SoupSOUP 101-103entry 27 — the format doc's known oneThe falsifying case the sweep was meant to find became a finding instead.
Alpha Dance IIdeclares six partitions and holds all six and still loses 21 of one volume's 22 samples;Library.1andLibrary.3are the same shape. That is a run of blocks lost inside a partition, so no header goes missing and the table's declared-against-present arithmetic sees nothing. 25 files on three.mdximages — #35, and the reasondeclared == presentmust not start being read as a clean bill of health.The five that do not cluster are single files: four with a corrupt rate byte and an otherwise perfect header (
EG 2MUTEat 0 Hz,M.VOICE A1andSYN 1at 519,HOUSE BASSat 1280) andLoop Soup's one directory record landing mid-sample. Those four are the files their entries placed, with one field unusable, so they are counted as damage rather than as mismatches.What a refusal does now
Skip-and-log, the house style, as a
Skippedcarrying amismatchflag counted apart in the summary and the manifest — ADR-0024's precedent one step on. A third result shape was rejected: a mismatch is a subset of not-written, and every consumer would grow a branch to say what one boolean says.The reason names every field that disagrees rather than the first, because what they disagree about together is the diagnosis:
against the old
payload does not start with an AKAI sample header, which was true of a payload that is mid-audio and of one that is a perfectly good sample under the wrong name alike. That is the honest lesson of #23: the refusal existed the whole time and told nobody which of four things was wrong, or that a directory entry was involved at all — so nobody checked whether it existed.Testing
The suite had no AKAI payload check, which is how a 42-byte slip survived four deliverables in a green run. The E-mu and Roland paths have asserted their audio against the disc for two deliverables each.
entry.size == words × 2 + header_len— 56 425 of 56 425. Plus the general invariant A sample payload whose header disagrees with its directory entry is extracted silently #23 asked for: no AKAI sample is written whose payload header names a different file.Advance Orchestraas the control with 2 236 samples and nothing wrong anywhere.0x81and0x9caccepted; a program (id 1) never handed to the sample parser; the name check exercised where no disc can exercise it.Whole-collection payload check re-established, not inherited — it was true before against the wrong offset, which is exactly what made it worthless: 70 of 70 discs, 89 156 WAVs, zero whose audio is not on the disc it came from. 275 silent files, 1 047 distinct rates from 6 000 to 49 999, none unreadable, none zero-length — all unchanged.
Roland, E-mu and ISO 9660 are untouched. The declared name and the generation bit reach the parser through
AkaiBackend.parse_sample, the routeEmu3BackendandRolandS7xxBackendalready use, soextract.pylearns no AKAI constant (ADR-0003); the only shared-path additions areSkipped.mismatchand aPayloadMismatchinsample/__init__.pythat any backend may raise.Is #25 unblocked?
Yes, with a limit that should be read before starting it.
#25 was deferred because displaced audio extracted as wrong files with nothing reporting it, and ADR-0023 names #23 as the standing evidence for that. That argument no longer holds: a displaced payload is now refused and named, per file and per disc, so recovering a short image's partitions no longer risks silently writing one sample's sound under another's name. The safety case for the deferral is answered.
The limit is the honest half. On all nine of those images the displacement lands mid-PCM and is caught by the id and valid tests, never by the name test. The guard against a displacement landing exactly on another sample's header — which is the case #25 will produce most of, since it will be reading whole partitions of shifted audio rather than one volume's tail — has zero positives on real data and is exercised only against a fixture. It is a comparison that cannot really be wrong, but it has not been shown right on a disc, and #25 should be attempted knowing that rather than treating this PR as having proved it.
#35 is the other thing #25's author should know: a rip can lose a run of blocks inside a partition without losing a header, so the nine images in #25's table are a floor and not the list.
Docs
docs/README.mdD19 row, and three entries in "What is not done": AKAI: a rip can lose a run of blocks inside a partition, and the table sees nothing #35's mid-partition damage, the name check's lack of real positives, and the valid byte's unread low bits.Verify
🤖 Generated with Claude Code