Skip to content

D21: an E-mu record is closed by the channel it declares, and found by either one - #40

Merged
bmxcode merged 1 commit into
mainfrom
d21-a-record-is-closed-by-the-channel-it-declares
Aug 24, 2026
Merged

D21: an E-mu record is closed by the channel it declares, and found by either one#40
bmxcode merged 1 commit into
mainfrom
d21-a-record-is-closed-by-the-channel-it-declares

Conversation

@bmxcode

@bmxcode bmxcode commented Aug 24, 2026

Copy link
Copy Markdown
Owner

What this is

Issue #39 reported three EIIIX/ESI discs each claiming a bank, returning no files and giving no reason — the ADR-0012 signature this project treats as a bug rather than a quirk. Twelve banks in all, ten of them on one disc.

None of them is the case ADR-0021 already explains. Every one declares a non-zero sample area, so OFF_BANK_SAMPLE_BYTES has nothing to say about any of them. The cause is one field read as something it is not, and it reaches a long way past those three discs.

The finding

+34 is the right channel's end pointer, not the record's length. It carried both names in fs/emu3.pyOFF_SAMPLE_END_R and OFF_SAMPLE_RECORD_LEN — and the walk took the record's extent from it unconditionally. That is correct only where the right-hand pointer set is what describes this record's audio, and on 10 274 of the 15 272 EIII/ESI records across seven discs the left-hand set is.

Four shapes the right-hand set takes when it is not describing the record it sits in:

Shape What the right-hand set holds What reading +34 as a length does Records
mirror-92 start_R = 0, end_R = end_L − 92 — the same channel counted from the payload's start instead of the record's an extent 92 bytes short, so the sample loses its last 46 frames 7 005
zeroed start_R = end_R = 0 an extent of 2, shorter than the header, so the record is dropped 872
fixed frame start_R = 92 + F, end_R = 92 + 2F − 2 for a constant allocation frame F — 1 MiB on E-mu Classics, 2 MiB on EIIIX Vol. 1 an address past the whole bank region, so the record is dropped 95
right-declared start_R = 92 with the left set not opening the audio (start_L = 0 on 1 371 of them) nothing: the record is never found 1 429

The last one is the sharpest, because docs/formats/emu3.md already recorded it: "Either set can be the single one — 542 records on eiv-studio … declare their one channel on the right", and "Read the set whose start is 92 and use it." That rule was applied to picking a loop and to nothing else. The EIII walk both located and sized a record from the left-hand pointer alone.

The mirror-92 shape answers a question docs/README.md had open since D17: "Either the reader is 90 bytes short on those samples or the extent field means something else." It was the reader, by 92 bytes.

The decision

A record's extent is closed by the end pointer of the set that opens its audio, and a record is found by either set opening it (ADR-0029).

  • The signature is 92 at +22 or at +26, deduplicated by address and yielded in address order, so which anchor found a record cannot change what is written.
  • The extent is end + 2 of the set whose start is 92 — the larger where both are.
  • Except on a confirmed two-channel record, where it is end_R + 2 and covers both blocks. Stated from the pointers alone: start_L == 92, start_R == end_L + 2, end_R − start_R == end_L − start_L. That is ADR-0026's three conditions without reference to the payload size — which matters, because the payload size is what is being computed.

What says it is right

Three things, none of them the pointer block agreeing with itself.

The stride to the next record. end_L + 2 equals the distance to the next record on 2 093 of ESI-32 General Midi's records; end_R + 2 equals it on 30.

The bank header's declared run — a different field, in a different structure. ADR-0021 measured a bank's last record ending exactly at 0x30 + 74 + 0x34 on 72 banks and "exactly 92 bytes — one sample header — short of it" on 19 more, and recorded the second population as a loose fit. It is this bug, seen from the bank header:

Disc banks with records ends exactly at the run's end before
ESI-32 General Midi 7 7 2
Protozoa 15 15 0
EIIIX Vol. 1 44 39 35
EIIIX Vol. 2 44 39 37
E-mu Classics 19 16 8
Vintage 13 13 4
Ditto Drums 44 44 0
total 186 173 86

No bank on any disc is left in the "92 bytes short" bucket. The reference bank says the same on its own: 8M GeneralMidi X now yields 531 records totalling 8 248 316 bytes, which is its declared run to the byte, where it previously yielded 452 records and 7 345 200 bytes inside a run nothing filled.

The loops splice. The extent decides how much audio each sample is, so counts moving is not itself a reason to believe them. 838 of ESI-32 General Midi's loops and 1 082 of Protozoa's are newly admitted — exactly the loops ADR-0025 refused because the declared end ran past the payload, and with the corrected extent they fit without being clamped, which is the move that record showed destroys a loop. Scored by the format doc's own shape and join tests, with its controls:

Disc group scored shape r control seamless control seamless
ESI-32 General Midi loop newly admitted 838 +0.87 +0.01 87 % 36 %
ESI-32 General Midi record newly found 130 +0.90 −0.03 80 % 29 %
Protozoa loop already produced 905 +0.85 +0.02 83 % 38 %
Protozoa loop newly admitted 1 082 +0.82 −0.01 90 % 32 %
Protozoa record newly found 330 +0.77 −0.06 87 % 34 %
EIIIX Vol. 1 loop already produced 413 +0.96 +0.02 90 % 36 %
EIIIX Vol. 1 record newly found 133 +0.99 −0.10 94 % 23 %
Vintage record newly found 250 +0.94 −0.03 85 % 23 %

The record newly found rows are the right-declared and zeroed-right-set records, and they answer the obvious worry about widening a signature that scans through megabytes of audio. A false hit inside PCM does not carry a loop that splices at +0.9 against a control at zero.

What moves

Disc Samples With a loop Stereo
ESI-32 General Midi 2 265 → 2 635 107 → 1 778 28 → 28
Protozoa 5 852 → 6 595 1 689 → 5 244 8 → 8
EIIIX Vol. 1 1 189 → 1 248 1 157 → 1 215 601 → 601
EIIIX Vol. 2 1 333 → 1 337 1 260 → 1 264 592 → 592
E-mu Classics — → 1 516 — → 1 435 — → 185
Vintage — → 993 — → 953 — → 2
Ditto Drums 74 → 948 6 → 948 0

The collection goes from 104 921 samples to 109 554, and E-mu from 14 738 on seven discs to 19 371 on ten. All twelve banks of #39 yield files; the only volumes left empty on those discs are index banks and the sampler's own code banks, both of which already carry their note.

Anyone who extracted an EIII or ESI disc before this should do it again. On ESI-32 General Midi and Protozoa most samples were 46 frames short at the end, and on every disc some samples were missing entirely.

What does not move, and why that matters

The three E-IV discs are byte-identical — 449, 2 822 and 828 samples, same payload digests. They size a record from their own big-endian sample directory and never read +34 (ADR-0020), so they are the control that says nothing shared was disturbed.

The stereo counts are unchanged on every disc that had them. Changing how long a record is did not change what shape it is.

Payload overlaps into the following record fall rather than rise — 439 to 238 on EIIIX Vol. 1, 236 to 188 on EIIIX Vol. 2 — and the newly found right-declared records land in the gaps between existing records rather than inside them: 0 of 353 on ESI-32 General Midi, 0 of 607 on Protozoa, 1 of 18 on EIIIX Vol. 1.

Every WAV still matches the disc it came from. 73 of 73 discs, 109 554 payloads, comparing multisets of SHA-256 over the PCM per disc; the ten E-mu discs were re-measured for this deliverable and match on all 19 371.

Protozoa's trombones resolve

ADR-0026 identified six records whose "first half is byte for byte the whole of a one-channel record of the same name in another bank"Trom B2, 16 756 bytes inside a 33 512-byte payload, with nothing on the disc matching the second half. There was no second half. Read at its declared length, Proteus1PresetsX's Trom B2 is 16 764 bytes and byte-identical to Vintage PresetsX's and Vintage InstrmtX's, as are Trom E3, Trom C5, Trom D4 and Trom G4.

That has a consequence for ADR-0026 worth stating plainly. Its gate's third condition caught 65 records that declared a two-channel shape and were not stereo; under the corrected extent that population is zero on all ten discs, because those records only ever looked like a split when sized at twice their length. The condition stays — it is what makes the two-channel test exact — but it is now an unexercised gate, and that is recorded rather than glossed.

What this deliberately does not claim

The whole-extent loop guard is not fixed here. Ditto Drums writes a loop spanning the entire sample on 934 of its 948 records, starting at frame 6 rather than frame 0, and sample/emu3.py only refuses a whole-extent loop that starts at exactly 0. The same pattern already ships on EIIIX Vol. 1 (460) and EIIIX Vol. 2 (320) and predates this deliverable. Folding it in would move the loop counts for two unrelated reasons at once and make neither attributable, so it is recorded in docs/formats/emu3.md, docs/README.md and the README's "what doesn't work yet" instead.

A fifth shape of right-hand set would still be silent. The rule refuses a record where neither set opens the audio at 92. That is a drop of exactly the kind this change exists to remove; it would present as a bank yielding fewer records than its run declares, and the new bank-run test is what would catch it.

Tests

The disc suite skips without SAMPLERDISC_TEST_DISCS, so the mechanism is pinned in both places.

  • tests/test_emu3.py gains synthetic coverage of record_extent — all four right-hand-set shapes, the two-channel exception, and the two refusals — plus walk-level tests that a bank of right-declared records and a record with its unused side zeroed both read. These run in CI, where there are no discs.
  • tests/test_discs.py re-pins the four EIII/ESI discs and adds the three new ones; asserts the three E-IV rows unmoved; pins the twelve banks of emu3: three EIIIX volumes claim a bank and return no files with no note #39 by shape as well as by count, so the day one stops holding it says which of the three ways it stopped; and asserts the bank-run agreement above, since that is the independent evidence the decision rests on and is exactly what a later simplification would quietly break.

One piece of shared test infrastructure changed. _pinned_disc finds a disc by size, on the measured assumption that sizes are distinct across the collection. A whole publisher's series arriving at once is where that stops holding: E-mu Classics shares 526 723 072 bytes with Vol. 03 – Orchestral, and Studio Essentials shares 399 077 376 with More Studio Essentials. The pin now falls back to a digest of the image's first megabyte where two share a size — still a property of the disc rather than of its filename (ADR-0004) — and is consulted only on a collision, so every other pin is untouched.

Closes #39.

🤖 Generated with Claude Code

`+34` is the right channel's end pointer, not the record's length. The
walk took the extent from it unconditionally, which is right only where
the right-hand set describes the record -- and on 10 274 of the 15 272
EIII/ESI records here the left-hand set does.

Closes #39.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bmxcode
bmxcode merged commit 361bc45 into main Aug 24, 2026
1 check passed
@bmxcode
bmxcode deleted the d21-a-record-is-closed-by-the-channel-it-declares branch August 24, 2026 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

emu3: three EIIIX volumes claim a bank and return no files with no note

1 participant