AKAI: read every partition, from the table the disk declares - #26
Merged
Conversation
An AKAI disc is a disk image and the walk stopped at the partition the origin resolved to, so 44 discs listed 448 volumes and 14 670 files of the 2 154 and 68 997 they hold (#22). The disk declares its partitions: a table at 0x4500 of the first one, carrying a count, that many sizes in blocks and the disk's total. All 44 discs have one and on all 44 the sizes sum to the total. A partition is read only where a header sits at the position the table gives and restates the size it was given, and a declared position with no header is skipped rather than searched for. Block numbers count from the partition they are in, so a Volume and a File now carry the offset theirs count from and read_file adds it. Extraction nests under the partition, since volume names repeat. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bmxcode
added a commit
that referenced
this pull request
Aug 21, 2026
) The "Only the first partition of an AKAI disc is read" entry under Unreleased / Known limits contradicted the Added bullet in the same section: PR #26 read every partition from the table at 0x4500 and closed issue #22, and this entry should have gone with it. Its own explanation was also superseded — partitions come from the table, not from tiling at multiples of the size at 0x00, and their sizes are not all equal (ADR-0023). What survives is the narrower limit ADR-0023 states plainly: a declared partition with no header at its declared position is skipped rather than searched for, leaving roughly fifteen thousand readable files unread on the nine short images, which is issue #25. That is what the bullet now says. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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 #22.
An AKAI disc is a disk image: the sampler wrote a hard disk of several partitions and the CD is a copy of it.
AkaiBackend.volumes()walked the partition the origin resolved to and stopped, so across the 44 AKAI discs on the shelf it listed 448 volumes and 14 670 files of the 2 154 volumes and 68 997 files they hold.Loop Soupreported 7 volumes; it has 60.The partition table exists, and this reads it
#22 recorded partitions as tiling at multiples of the size declared at
0x00— an observation across 44 discs, not a field anyone had read — and asked, before anything was built on it, whether the disc declares a table anywhere. It does.At
0x4500of the first partition, past the largest allocation map that fits in front of it:+0x00+0x01+0x02+2n+2All 44 AKAI discs carry one, and on all 44 the sizes sum to the total.
Loop Soupdeclares nine partitions — eight of 7680 blocks and a last of 4095, totalling 65 535, which is the ceiling u16 block numbers imply.That last entry is what tiling could not have got right. The sizes are not all equal: the final partition is a remainder. Tiling places the same partitions everywhere both rules can be applied, and then invents a fourteenth on
AKAI.S3000.Sound.Library.1at block 65 535 that the disk does not declare. This is the register ADR-0021 settled one deliverable ago: a field the disc states beats a bound inferred between structures.The other candidate #22 named — the 100 u16 at
0x02that ramp by 3333 on every disc — declares nothing. Its 196 bytes are byte-identical on every disc and every partition, so nothing in it varies with anything. What does vary is the pair after it: the u16 at0xC6is the block count plus 47573 and the u16 at0xC8is 47, on all 276 partitions measured. That is the header restating its own size, and it is what confirms a partition is where the table says without trusting the arithmetic that placed it.What it costs to get wrong, and how this is checked
Block numbers are relative to the partition, so the same number means a different place in each one, and a read with the partition term dropped returns another partition's audio rather than an error. Three independent checks say it is right:
tests/test_discs.py(_AKAI_FIRST_PARTITION) precisely because the failure mode here is plausible output rather than an exception.Loop Soupall 3 200 agree exactly, and a disc test asserts it.MULTI FILE— typem, all onLibrary.1— whose chain runs exactly one block past what its size needs. Named in the test rather than tolerated, so a second kind of disagreement fails.The content is plainly the disc's own:
Loop Soup's partition 1 ends atSOUP 115-117and its partition 2 opens atSOUP 120.The three discs #22 could not explain
AKAI.S3000.Sound.Library.6,.7andElektra Voxare not laid out differently. They are short images. Where a declared partition has no header at its position, one turns up earlier — and every displacement is a whole number of 32 KB MDX blocks, accumulating down the disc (Library.6by 60 then 68;Elektra Voxfrom 424 to 2888 over nine partitions). All are.mdx. That is the finding #17 reached from inside partition 1, now measurable from outside it.Those partitions are not recovered here, and #25 records why with the numbers: the header's constant field is a sawtooth as PCM so audio matches it (374 blocks of free space on one disc), filtering those by "does a volume yield a file" loses real partitions elsewhere, and 7 723 of the ~15 000 files a search would gain are on
Kickin' Lunatic Beats 2 CD1, whose partition 1 already extracts nine samples that are not their own (#23).What changes for a user
Extraction paths. AKAI samples now land in
out/partition-1/VOLUME 001/…where they landed inout/VOLUME 001/…, on every AKAI disc including single-partition ones. Nearly every partition of a disc has aVOLUME 001, so a flat layout put two libraries' audio in one directory underunique_pathsuffixes with nothing saying which was which — not a lost file, an unusable one. The batch manifest keys volumes by partition and name for the same reason. Making the layout conditional on a disc having several partitions was considered and rejected: a layout that varies by disc is worse than one that moved once.listreports the table:9 partitions declared, 9 present in this image, then volumes under their partition.Kickin' Lunatic Beats 2 CD1prints eleven declared and one present — its missing ten used to be an absence with nothing to see.What this does not claim
+0x01, the 196-byte constant and the0xC8tail are unread. They are recorded as unread.Also here
allocation_maptakes its block count from a header that restates it, rather than from what the image can hold. A partition the image ends inside now gets the map for the blocks present, which is what stopped two volumes onProSamples vol.17being empty and silent — the ADR-0012 signature raised by a short image rather than by a disc declaring nonsense. ADR-0022's "no map, no note" is narrowed to a count that is absent or unvouched for, and amended in place to say so.Verification
ruff check,ruff format --check,pytest -qand the installed entrypoint all pass.SAMPLERDISC_TEST_DISCSagainst the 38-image regression set: 433 passed, no skips (170 before this branch, on the disc module alone; 181 after, plus the new synthetic tests). Collection-wide, by listing: 71 of 79 images claimed, 2 578 volumes and 110 989 files, from 872 and 56 662.🤖 Generated with Claude Code