I argued `highest_rate` had no case because ADV's higher-rate presentation is dual-mono while its louder one is mono-in-stereo, so the extra bytes buy a duplicated channel rather than fidelity. The Decoder tested that disc-wide over the 28 three-stream cues: the stream-3/stream-2 size ratio runs min 0.0778, median 1.2565, max 2.9163, sd 0.5057, with only 12 of 28 within 15% of 1.0, and declared rates scatter with them. A 37x spread is not a duplicated channel. The CHANNEL MEASUREMENT STANDS -- ADV chunk 1 is mono-in-stereo and chunk 2 is dual-mono at -8.318574, this port's own decode, which the Decoder could not re-run and did not dispute. What fails is the step from one asset to the format. NOTHING IN THE EXPORT CHANGES. `loudest` is a per-asset content rule -- it reads the peak of the streams in front of it -- so a scattering structural ratio cannot undermine it. What changes is the REASON, in four places: authored/audio.json's presentation_why, the selector comment in audio.rs, BLOCKED.md's row, and DECISIONS.md. The honest statement is narrower: `highest_rate` was never refuted, it was never argued for, and neither is `loudest`. That is why the entry is marked CHOSEN rather than measured, and why one capture deletes it. Recorded on the pattern rather than just the instance: this is the third claim of mine in two iterations that generalised a single-asset observation, after "the chunks are two stems" and "everything the sequencer paces off rest.t is late". All three were true of the thing I looked at. The failure is reaching for the rule a measurement would imply if it held everywhere and writing that down in the same breath as the measurement. Also noted, not mine and not affecting export_voice: S12B's three streams are byte-size identical, and BIRD_224 is three-stream while not being a movie cue. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
164 lines
10 KiB
JSON
164 lines
10 KiB
JSON
{
|
|
"format": "sylpheed.audio/1",
|
|
"_": [
|
|
"Menu audio. EVERY VALUE IN THIS FILE IS MEASURED OR CHOSEN -- none of it is",
|
|
"in a data file the exporter can read, which is why it is here and not in the",
|
|
"exporter. `measured` and `chosen` are NOT the same thing and this file keeps",
|
|
"them apart: a measurement is deleted when the disc states it, a choice is",
|
|
"deleted when somebody measures it.",
|
|
"",
|
|
"Two different kinds of not-on-the-disc live in this file and they are not",
|
|
"interchangeable:",
|
|
"",
|
|
" * `se` -- MEASURED. `Static.slb` is a delimiter-less run of whole 2048-byte",
|
|
" XMA1 packets: no RIFF, no seek chunk, no XACT container. A wave is defined",
|
|
" ONLY by (offset, packet_count), and both numbers come from the running",
|
|
" game, not from the file. HANDOFF Q8. Delete a row the day a table on the",
|
|
" disc states the same thing.",
|
|
"",
|
|
" * `bgm` -- MEASURED, and only the LOOP POLICY beside it is chosen. HANDOFF",
|
|
" Q10's negative is about the TABLES: `SOUNDS`, `FILES` and the bank headers",
|
|
" name no screen. The executable does -- cue 1103 = `BGM_103`, corroborated",
|
|
" by a byte-for-byte match against what the XMA probe saw at the main menu.",
|
|
" An earlier draft read the negative as unbounded, picked a track at random",
|
|
" and called it authored. See the `bgm._` block for what that cost.",
|
|
"",
|
|
"The exporter reads this file and emits `export/audio/**` from it. It holds no",
|
|
"cue table of its own: a measured offset compiled into a Rust `const` is a",
|
|
"measurement wearing the costume of a decoded field, and MISSION section 3 is",
|
|
"explicit that measured values live here."
|
|
],
|
|
"se": {
|
|
"_": [
|
|
"MEASURED, HANDOFF Q8, and the RE agent retracted an earlier 'cannot be",
|
|
"extracted' to publish these. The waves were located BY PLAYING THEM: Canary",
|
|
"with `--xma_param_probe=true` prints a stream's packet count and first 32",
|
|
"bytes when it is played, and searching those bytes in the bank gives the",
|
|
"offset.",
|
|
"",
|
|
"WARNING, from the same finding: the file order is NOT cue-id order. These",
|
|
"cannot be counted out, and an index here would be a fabrication.",
|
|
"",
|
|
"`name_match` is the authors' own identifier GUESSED BY NAME. It is carried",
|
|
"so the guess is not lost and is never presented as the measurement. Where",
|
|
"the RE agent did not separate two candidates, there is no name at all --",
|
|
"an absent `name_match` means nobody has claimed one, never that the",
|
|
"BINDING is unknown. The binding is the measured part.",
|
|
"",
|
|
"All three are mono 48 kHz; that is the RE agent's statement in",
|
|
"`sylpheed_formats::media::se_wave_riff`, not something re-derived here."
|
|
],
|
|
"move": {
|
|
"bank": "Static.slb",
|
|
"offset": "0x1ec0",
|
|
"packets": 4,
|
|
"channels": 1,
|
|
"rate": 48000,
|
|
"name_match": "SE_UI_CURSOR",
|
|
"why": "HANDOFF Q8, measured: the d-pad move cue, 8 192 B / 0.533 s, reproduced across two boots. Left/right play nothing at all, which is a measurement too and is why there is no `left`/`right` row here rather than a silent file."
|
|
},
|
|
"confirm": {
|
|
"bank": "Static.slb",
|
|
"offset": "0x5d6c0",
|
|
"packets": 6,
|
|
"channels": 1,
|
|
"rate": 48000,
|
|
"why": "HANDOFF Q8, measured: the (A) confirm cue, 12 288 B / 1.016 s. NO `name_match`: Q8 is explicit that (A)'s wave was not separated between `SE_UI_DECIDE` and `SE_UI_SUB_WIN_OPN`, so naming it would invent the one thing the measurement did not settle."
|
|
},
|
|
"back": {
|
|
"bank": "Static.slb",
|
|
"offset": "0x0ec0",
|
|
"packets": 2,
|
|
"channels": 1,
|
|
"rate": 48000,
|
|
"why": "HANDOFF Q8, measured: the (B) back cue, 4 096 B / 0.344 s, reproduced across two boots. No `name_match` for the same reason as `confirm` -- Q8 names no identifier for it."
|
|
}
|
|
},
|
|
"bgm": {
|
|
"_": [
|
|
"MEASURED, NOT CHOSEN -- and the port got this wrong for one iteration.",
|
|
"",
|
|
"`docs/port/BLOCKED.md` carried a row reading 'not on the disc ... the port",
|
|
"is choosing a track, and that choice is authored', and the first draft of",
|
|
"this file duly picked BGM_001 and labelled it arbitrary. That row was not",
|
|
"stale: `BGM_103` is in HANDOFF at `9ca1eb5`, which is the exact commit the",
|
|
"row says it was reconciled against. It was WRONG WHEN WRITTEN.",
|
|
"",
|
|
"What HANDOFF actually says is a negative with a stated reach, and the reach",
|
|
"is what the port dropped: the *tables* cannot say which BGM a screen plays",
|
|
"-- `SOUNDS`, `FILES` and the bank headers name no screen. The EXECUTABLE",
|
|
"can. `GamePart_Title`'s phase handler `sub_821C5580` carries `li r5, 1103`",
|
|
"into a sound call, cue 1103 is `BGM_103`, and `BGM_103.slb`'s two declared",
|
|
"waves (3 876 864 / 3 930 112 B) are byte-for-byte the two streams the XMA",
|
|
"probe saw decoding at the main menu. Static code, disc census and runtime",
|
|
"agree. HANDOFF's own words: 'The port does not have to choose a track.'",
|
|
"",
|
|
"So this section is a CITATION, not a decision. It lives in `authored/`",
|
|
"only because the binding is in the .xex and the exporter reads data files,",
|
|
"not code -- and it must be deleted the day something the exporter can read",
|
|
"states it. The loop policy below IS still a decision."
|
|
],
|
|
"main_menu": {
|
|
"bank": "BGM_103.slb",
|
|
"loop": "restart",
|
|
"kind": "measured",
|
|
"why": "MEASURED, HANDOFF Q10 -- NOT a port choice. `GamePart_Title`'s phase handler `sub_821C5580` plays cue 1103 = `BGM_103`, and `BGM_103.slb`'s two declared waves (3 876 864 / 3 930 112 B) are byte-for-byte the two streams the XMA probe saw decoding at the main menu. Static code, disc census and runtime all agree; see docs/re/menu-audio-cues.md and docs/re/structures/bgm-two-stems.md. The name carries its `.slb` extension because that is what `sound.pak` hashes -- `BGM_103` alone resolves to nothing, which is how the first draft of this file failed.",
|
|
"loop_why": "AUTHORED, and it will be AUDIBLY WRONG AT THE SEAM. HANDOFF Q10: no loop-point field has been identified anywhere, so the file carries no marked restart. `restart` replays from sample 0, which means the listener hears the track's own fade-out and the silence after it before the music comes back. Trimming to the fade would sound better and would be worse: it would INVENT a loop point, and an invented one is indistinguishable from a decoded one a month later. The seam stays ugly until a loop point is measured or a capture of the real menu looping settles it.",
|
|
"stems": "sum",
|
|
"stems_why": "MEASURED, HANDOFF Q10: a bank is exactly TWO waves of identical duration (32/32 banks on the disc), sample-synchronous -- transient correlation peaks at lag 0.00 s over +/-5 s and both stop at the same millisecond. Concatenating them plays the piece twice, the second time as a bass-less stem; that was the previous reading and it is refuted. Emitting two files would be wrong for a second reason: MODDING rule 1 is one logical asset, one file, and handing a modder two stems to line up by hand is the reassembly the exporter exists to have already done. WHAT IS SUMMED IS SETTLED; WHAT WAVE 1 IS, IS NOT -- HANDOFF calls it quieter, far more L/R-decorrelated and almost bass-free, so it reads as a surround-rear pair OR a second intensity layer, and `ChannelMask` is 0x0002 on both so the file will not say. A unity sum is right under either reading; a weighting would only be justified once that is settled."
|
|
}
|
|
},
|
|
"voice": {
|
|
"_": [
|
|
"WHICH PRESENTATION of a cutscene's voice to export. CHOSEN, not measured and",
|
|
"not decoded -- delete this the day a capture says which one the game plays.",
|
|
"",
|
|
"A voice region carries THREE PRESENTATIONS OF ONE TAKE (decoded disc-wide by",
|
|
"the Decoder: 258 inter-descriptor spans hold one stream, 28 hold three, none",
|
|
"holds two). The exporter drops the leading one, which this port measured to",
|
|
"be the tail of the others, and must then pick between the two full-length",
|
|
"ones. Nothing on the disc ranks them: wEncodeOptions, channel count and",
|
|
"channel mask are byte-identical across them.",
|
|
"",
|
|
"This lives here rather than in the exporter because MISSION section 3 puts a",
|
|
"value we chose in authored/ with a why. A selection rule compiled into Rust",
|
|
"reads like something the exporter derived, and nobody deletes what nobody",
|
|
"can see."
|
|
],
|
|
"presentation": "loudest",
|
|
"presentation_why": [
|
|
"`loudest` = the full-length stream whose peak is nearest full scale.",
|
|
"",
|
|
"IT USED TO BE `highest_rate`, on the Decoder's recommendation, and that",
|
|
"recommendation was WITHDRAWN as self-contradictory -- it read 'the",
|
|
"highest-rate, highest-gain one is chunk 1', and those two criteria select",
|
|
"different streams: ADV chunk 1 is 1118268 B at 0.0 dBFS, chunk 2 is",
|
|
"1171516 B at -8.3 dBFS.",
|
|
"",
|
|
"WHY `loudest` AND NOT `highest_rate`: this is a PER-ASSET CONTENT choice,",
|
|
"and that is the whole of its justification. The disc masters its other audio",
|
|
"near full scale -- the SE cues decode to +0.18 dBFS -- and S00A's only",
|
|
"surviving full-length stream is its louder one at -4.2 dBFS, so `loudest`",
|
|
"makes the two cutscenes' dialogue sit at comparable levels instead of 4.4 dB",
|
|
"apart. Neither half is strong alone; together they are what there is.",
|
|
"",
|
|
"⚠️ A STRUCTURAL ARGUMENT WAS OFFERED HERE AND IS WITHDRAWN. It said ADV",
|
|
"chunk 1 is mono-in-stereo (channel 2 digitally silent) while chunk 2 is",
|
|
"dual-mono (channels identical at -8.318574), therefore the extra bytes",
|
|
"encode a duplicated channel rather than fidelity, therefore the rate",
|
|
"argument collapses. The CHANNEL MEASUREMENT stands -- it is ADV's, and it is",
|
|
"this port's own. THE GENERALISATION DOES NOT. The Decoder tested it",
|
|
"disc-wide over the 28 three-stream cues: the stream-3/stream-2 size ratio",
|
|
"runs min 0.0778, median 1.2565, max 2.9163, sd 0.5057, with only 12 of 28",
|
|
"within 15% of 1.0, and declared rates scatter with them (S06A: 5661 against",
|
|
"16513 B/s). A 37x spread is not a duplicated channel.",
|
|
"",
|
|
"So `highest_rate` was not refuted as a rule; it was simply never argued for,",
|
|
"and neither was this. That is why the entry is CHOSEN and why it says so.",
|
|
"",
|
|
"STILL A CHOICE. One capture of the intro with dialogue audible settles it,",
|
|
"and it is the last unforced decision in the voice pipeline."
|
|
]
|
|
}
|
|
}
|