diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index 98100dae..bacf0b7c 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -420,10 +420,28 @@ take**, one clipped by our own guard. That was the last open one and it is shut. ๐Ÿ”ด **One change you have NOT made yet and should: stop summing chunk 1 and chunk 2.** They are the same take, not two stems โ€” `ADV` chunk 2 is 0.60 ร— chunk 1 (residual 26.8 dB down), `S00A` chunk 2 is digital silence. Summing a take with a -scaled copy of itself adds ~4 dB and colours it. **Take one stream**, the -highest-rate one (chunk 1). Dropping silent chunks was the right instinct; this -is the same defect one step further out. โ” *Why* the disc stores three -presentations is not answered. +scaled copy of itself adds ~4 dB and colours it. **Take one stream.** + +๐Ÿ”ด **Which stream โ€” my instruction was self-contradictory and you were right to +flag it.** I wrote "the highest-rate, highest-gain one (chunk 1)". Those two +criteria select *different* streams: on `ADV` chunk 1 is 0.0 dBFS at 1 118 268 B +and chunk 2 is โˆ’8.3 dBFS at 1 171 516 B. You implemented "highest rate" +faithfully and got the quieter one โ€” the opposite of what the parenthetical +meant. Withdrawn; keep it as an authored ๐ŸŸก exactly as you have it. + +โœ… **What I can decode is the rate, and only the rate.** The `fmt ` chunk is a +32-byte `XMAWAVEFORMAT`; `+0x20` is a declared `PsuedoBytesPerSec` โ€” 8 142 and +8 530 for `ADV`'s two, matching the computed rates to 0.02 %, and 48 000 Hz at +`+0x24`. โ” **But `wEncodeOptions` (`0x10d6`), channel count and channel mask are +byte-identical across the presentations.** Nothing in the header ranks them. Your +"more bytes is consistent with a better encode and also with the opposite" is +exactly right and the file will not adjudicate it. + +โš ๏ธ Also: **do not trust `sylpheed-cli audio info` on these.** Its "16 channels / +4310 Hz / 2-bit" is `wBitsPerSample`, `wEncodeOptions` and the channel fields +read at wrong offsets. Its reader is misaligned for XMA1. + +โ” *Why* the disc stores three presentations is not answered. โš ๏ธ On your offer to convert the 504 464 B constant: **don't spend the decode.** It is structural, not proportional โ€” identical on all 17 despite differing diff --git a/docs/re/structures/voice-region-leading-chunk.md b/docs/re/structures/voice-region-leading-chunk.md index 3ed68c15..34578560 100644 --- a/docs/re/structures/voice-region-leading-chunk.md +++ b/docs/re/structures/voice-region-leading-chunk.md @@ -222,10 +222,50 @@ the reason the exporter's existing behaviour is right is now on the record. stems.** `ADV` chunk 2 is `0.60 ร—` chunk 1 with the residual 26.8 dB down; `S00A` chunk 2 is digital silence. Summing a take with a scaled copy of itself adds ~4 dB and colours it; summing it with silence at `1/n` costs 6.02 dB. **Take -one stream.** On the evidence so far the highest-rate, highest-gain one is chunk -1. โ” *Why* the disc stores three presentations โ€” quality tiers, a mix the engine +one stream.** + +### ๐Ÿ”ด Which stream โ€” my recommendation was self-contradictory, and is withdrawn + +This page said *"the highest-rate, highest-gain one is chunk 1"*. **Those two +criteria do not select the same stream, and the sentence should never have joined +them.** On `ADV`, chunk 1 is 1 118 268 B at **0.0 dBFS** and chunk 2 is +1 171 516 B at **โˆ’8.3 dBFS**: chunk 2 has the higher rate and the *lower* level. +The port implemented "highest rate", correctly, and thereby selected the quieter +presentation โ€” the opposite of what the parenthetical intended. My error, and the +port caught it by checking the consequence rather than the instruction. + +**What the header does decode.** The `fmt ` chunk is a 32-byte `XMAWAVEFORMAT`, +little-endian, and `+0x20` is `PsuedoBytesPerSec` โ€” a **declared** field, not an +inference: + +| | `ADV` chunk 1 | `ADV` chunk 2 | `S00A` chunk 1 | +|---|---|---|---| +| `+0x20` declared bytes/sec | **8 142** | **8 530** | **13 485** | +| computed from size รท duration | 8 143.3 | 8 531.0 | 13 487.3 | +| `+0x24` sample rate | 48 000 | 48 000 | 48 000 | +| `+0x18` `wEncodeOptions` | `0x10d6` | `0x10d6` | `0x10d6` | +| `+0x31/+0x32` channels / mask | 2 / `0x0002` | 2 / `0x0002` | 2 / `0x0002` | + +โœ… So the **rate is decoded** and agrees with the measured one to ~0.02 %. +โ” **But nothing in the header ranks the presentations.** `wEncodeOptions`, +channel count and channel mask are byte-identical across them. The header says +how fast each stream is, and says nothing about which one the game plays. + +๐ŸŸก **So stream selection is an authored choice, and the port must know it is +authoring.** It is flagged in the port's manifest with the level consequence +stated, which is the right handling. **This is settleable in one emulator run** โ€” +a capture of the intro with the dialogue audible tells you which level the game +plays โ€” and it has not been done. + +โ” *Why* the disc stores three presentations โ€” quality tiers, a mix the engine selects between, an authoring artefact โ€” is not answered here. +โš ๏ธ Note for anyone reading our own tooling: `sylpheed-cli audio info` reports +these chunks as *16 channels, 4310 Hz, 2-bit*. Those are the `wBitsPerSample` +(16), `wEncodeOptions` (`0x10d6` = 4310) and channel fields read at the wrong +offsets. The header above is the correct layout; the CLI's reader is misaligned +for XMA1 and should not be used on these. + โš ๏ธ **Do not "fix" it by concatenating.** The port measured a concatenated region at 359 s against a 137 s movie.