diff --git a/crates/sylpheed-formats/examples/voice_region_chunk_census.rs b/crates/sylpheed-formats/examples/voice_region_chunk_census.rs new file mode 100644 index 00000000..38733412 --- /dev/null +++ b/crates/sylpheed-formats/examples/voice_region_chunk_census.rs @@ -0,0 +1,50 @@ +//! How many voice regions hold three chunks? A COUNT, stated with its population. +//! +//! `voice-region-starts-late.md` published "8 of 10 three-chunk regions start +//! mid-stream". The port agent counts **25** three-chunk regions. Mine was not a +//! count: the audit that produced it was cut short and I read a partial file as a +//! complete one โ€” it ends mid-list with no summary line. +//! +//! This does the cheap half properly. It does not step backwards looking for the +//! clip; it resolves each region once and counts its chunks, and it prints the +//! population, the coverage and the skips **in the same output** so a truncated run +//! cannot be mistaken for a complete one. +//! +//! cargo run -p sylpheed-formats --example voice_region_chunk_census + +use sylpheed_formats::media::{self, DirectorySource, DiscSource}; +use sylpheed_formats::movie_manifest; +use sylpheed_formats::slb::{self, VoiceLang}; +use std::collections::BTreeMap; + +fn main() { + let disc = std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC"); + let src = DirectorySource::new(std::path::PathBuf::from(&disc)); + let tpak = src.open_pak("dat/tables.pak").expect("tables.pak"); + let manifest = tpak + .entries().iter() + .find_map(|e| tpak.read(e).ok().filter(|b| movie_manifest::is_manifest(b))) + .expect("manifest"); + let movies: Vec = movie_manifest::parse(&manifest).into_iter().map(|m| m.movie).collect(); + let total = movies.len(); + + let mut hist: BTreeMap> = BTreeMap::new(); + let (mut resolved, mut unresolved, mut unreadable) = (0, 0, 0); + for movie in movies { + let Some((start, end)) = media::resolve_movie_voice_region(&src, &movie, VoiceLang::English) + else { unresolved += 1; continue }; + let Ok(b) = src.read_segment_range("dat/sound", start, (end - start) as usize) + else { unreadable += 1; continue }; + resolved += 1; + hist.entry(slb::to_xma_riffs(&b).len()).or_default().push(movie); + } + println!("POPULATION: {total} movies in the manifest"); + println!("COVERAGE: {resolved} resolved and read, {unresolved} unresolved, {unreadable} unreadable"); + println!(" {} accounted for\n", resolved + unresolved + unreadable); + for (n, ms) in &hist { + println!(" {n} chunk(s): {:>3} region(s) {}", ms.len(), + ms.iter().cloned().collect::>().join(" ")); + } + println!("\nTHREE-CHUNK REGIONS: {}", hist.get(&3).map(|v| v.len()).unwrap_or(0)); + println!("--- END OF CENSUS (if this line is missing, the run did not finish) ---"); +} diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index b9fd0e28..bc15beec 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -2555,8 +2555,16 @@ minimum; `[0.0, 61.93)` and `[0.25, 62.18)` are not separated. One boot, one ban [`menu-bgm-loop-measured.md`](../re/structures/menu-bgm-loop-measured.md) ยท [series](../re/data/menu-bgm-loop-measured.txt) -๐Ÿ”ด **And a correction you should carry:** my "8 of 10 three-chunk regions start -mid-stream" is **a ratio over an unknown fraction of the population** โ€” that audit +โœ… **The population is now counted properly, and your 25 is right.** 104 movies, +95 resolved, **70 one-chunk and 25 three-chunk**. Cross-referencing the fix's own +complete sweep: **all 17** changed regions are three-chunk, **0** are one-chunk, and +**8 three-chunk regions were never affected** (`S02A S05A S07B S11A S12A S12B S13B +S15B`) โ€” which the 1.5 MB cap predicts, since a region only trips the filter if its +span exceeds it. So "specific to the multichannel regions" holds, with complete +populations on both sides โ€” but "all three-chunk regions were broken" does not. + +๐Ÿ”ด **The superseded version:** my "8 of 10 three-chunk regions start +mid-stream" was **a ratio over an unknown fraction of the population** โ€” that audit run was cut short and I read a partial file as complete (it ends mid-list with no summary line). Your count of 25 is not in conflict with mine; mine was not a count. The `ADV` verification and the fix's own sweep are unaffected โ€” that sweep ran to diff --git a/docs/re/data/voice-region-chunk-census.txt b/docs/re/data/voice-region-chunk-census.txt index 9a6f9c72..7cb48240 100644 --- a/docs/re/data/voice-region-chunk-census.txt +++ b/docs/re/data/voice-region-chunk-census.txt @@ -1,103 +1,9 @@ -104 movies in the manifest +POPULATION: 104 movies in the manifest +COVERAGE: 95 resolved and read, 9 unresolved, 0 unreadable + 104 accounted for -ADV 433930240.. 437044592 3114352 B chunks 3 leading STREAM (808304 B = 394 packets + 1392 B) -S00A 452798464.. 455499120 2700656 B chunks 3 leading STREAM (1324400 B = 646 packets + 1392 B) -S01A 456003584.. 460117360 4113776 B chunks 3 leading STREAM (1154416 B = 563 packets + 1392 B) -RT01A 437044592.. 437345648 301056 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT01B 437345648.. 437712240 366592 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT01C_1 437712240.. 438080880 368640 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT01C_2 438080880.. 438451568 370688 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S02A 460117360.. 461518192 1400832 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -S02B 462022656.. 463838576 1815920 B chunks 3 leading STREAM (431472 B = 210 packets + 1392 B) -S02C 464343040.. 469970288 5627248 B chunks 3 leading STREAM (1869168 B = 912 packets + 1392 B) -RT02A 438451568.. 438789488 337920 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT02B 438789488.. 439192944 403456 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT02C 439192944.. 439645552 452608 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT02D_1 439645552.. 439852400 206848 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT02D_2 439852400.. 440112496 260096 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s02A 430128496.. 430196080 67584 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s02H 430335344.. 430390640 55296 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S03A 470474752.. 472020336 1545584 B chunks 3 leading STREAM (253296 B = 123 packets + 1392 B) -RT03A 440112496.. 440448368 335872 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT03B 440448368.. 440730992 282624 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT03C 440730992.. 441144688 413696 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT03D 441144688.. 441773424 628736 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s03A 430128496.. 430196080 67584 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s03H 430335344.. 430390640 55296 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S04B 480507904.. 482938224 2430320 B chunks 3 leading STREAM (556400 B = 271 packets + 1392 B) -RT04A 441773424.. 442019184 245760 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT04B 442019184.. 442254704 235520 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s02A 430265712.. 430335344 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S05A 482938224.. 483433840 495616 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -RT05A 442254704.. 442578288 323584 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT05B 442578288.. 442938736 360448 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT05C 442938736.. 443143536 204800 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s02A 430128496.. 430196080 67584 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S06A 483938304.. 485457264 1518960 B chunks 3 leading STREAM (351600 B = 171 packets + 1392 B) -S06B 485961728.. 488908144 2946416 B chunks 3 leading STREAM (607600 B = 296 packets + 1392 B) -RT06A 443143536.. 443460976 317440 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT06B 443460976.. 443802992 342016 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT06C 443802992.. 444046704 243712 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT06D 444046704.. 444183920 137216 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s06A 430128496.. 430196080 67584 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s06H 430335344.. 430390640 55296 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S07A 489412608.. 491443568 2030960 B chunks 3 leading STREAM (505200 B = 246 packets + 1392 B) -S07B 491443568.. 491634032 190464 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -RT07A 444183920.. 444706160 522240 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT07B 444706160.. 444980592 274432 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT07C 444980592.. 445130096 149504 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s07A 430265712.. 430335344 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s07H 430390640.. 430464368 73728 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT08A 445130096.. 445326704 196608 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT08B 445326704.. 445517168 190464 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT08C 445517168.. 445676912 159744 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s08A 430265712.. 430335344 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S09B 492138496.. 493743472 1604976 B chunks 3 leading STREAM (177520 B = 86 packets + 1392 B) -RT09A 445676912.. 446000496 323584 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT09B 446000496.. 446485872 485376 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT09C 446485872.. 446748016 262144 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT09D 446748016.. 447149424 401408 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s09A 430196080.. 430265712 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s09H 430335344.. 430390640 55296 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT10A 447149424.. 447272304 122880 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT10B 447272304.. 447356272 83968 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S11A 501900656.. 502173040 272384 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -S11C 502677504.. 505619824 2942320 B chunks 3 leading STREAM (742768 B = 362 packets + 1392 B) -RT11A 447356272.. 447776112 419840 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT11B 447776112.. 447880560 104448 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT11C 447880560.. 448097648 217088 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s11A 430196080.. 430265712 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S12A 505619824.. 506191216 571392 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -S12B 506191216.. 506262896 71680 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -S12C 506767360.. 512406896 5639536 B chunks 3 leading STREAM (1844592 B = 900 packets + 1392 B) -RT12A 448097648.. 448374128 276480 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT12B_1 448374128.. 448544112 169984 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT12B_2 448544112.. 448767344 223232 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s07A 430265712.. 430335344 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s07H 430390640.. 430464368 73728 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S13A 512911360.. 514874736 1963376 B chunks 3 leading STREAM (402800 B = 196 packets + 1392 B) -S13B 514874736.. 515278192 403456 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -RT13A 448767344.. 449002864 235520 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT13B_1 449002864.. 449099120 96256 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT13B_2 449099120.. 449340784 241664 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s13A 430265712.. 430335344 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S14A 515782656.. 521794928 6012272 B chunks 3 leading STREAM (1817968 B = 887 packets + 1392 B) -RT14A 449340784.. 449721712 380928 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT14B 449721712.. 450033008 311296 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT14C 450033008.. 450280816 247808 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_DS_s14H 430390640.. 430464368 73728 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -S15A 522299392.. 524309872 2010480 B chunks 3 leading STREAM (255344 B = 124 packets + 1392 B) -S15B 524309872.. 525626736 1316864 B chunks 3 BANK HEADER (10240 B = 5 packets exactly) -S15C 526131200.. 529565040 3433840 B chunks 3 leading STREAM (931184 B = 454 packets + 1392 B) -RT15A 450280816.. 450985328 704512 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT15B 450985328.. 451282288 296960 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -RT15C 451282288.. 451614064 331776 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s15A 430196080.. 430265712 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s24A 430196080.. 430265712 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) -hokyu_LS_s27A 430196080.. 430265712 69632 B chunks 1 BANK HEADER (10240 B = 5 packets exactly) + 1 chunk(s): 70 region(s) RT01A RT01B RT01C_1 RT01C_2 RT02A RT02B RT02C RT02D_1 RT02D_2 hokyu_LS_s02A hokyu_LS_s02H RT03A RT03B RT03C RT03D hokyu_LS_s03A hokyu_LS_s03H RT04A RT04B hokyu_DS_s02A RT05A RT05B RT05C hokyu_LS_s02A RT06A RT06B RT06C RT06D hokyu_LS_s06A hokyu_LS_s06H RT07A RT07B RT07C hokyu_DS_s07A hokyu_DS_s07H RT08A RT08B RT08C hokyu_DS_s08A RT09A RT09B RT09C RT09D hokyu_LS_s09A hokyu_LS_s09H RT10A RT10B RT11A RT11B RT11C hokyu_LS_s11A RT12A RT12B_1 RT12B_2 hokyu_DS_s07A hokyu_DS_s07H RT13A RT13B_1 RT13B_2 hokyu_DS_s13A RT14A RT14B RT14C hokyu_DS_s14H RT15A RT15B RT15C hokyu_LS_s15A hokyu_LS_s24A hokyu_LS_s27A + 3 chunk(s): 25 region(s) ADV S00A S01A S02A S02B S02C S03A S04B S05A S06A S06B S07A S07B S09B S11A S11C S12A S12B S12C S13A S13B S14A S15A S15B S15C -78 region(s) open with a BANK HEADER (bank_header_len fires) -17 open with a leading STREAM -0 start at a RIFF -leading-stream length mod 2048, i.e. the derived data offset: - 1392 B x17 +THREE-CHUNK REGIONS: 25 +--- END OF CENSUS (if this line is missing, the run did not finish) --- diff --git a/docs/re/structures/voice-region-starts-late.md b/docs/re/structures/voice-region-starts-late.md index ed7f9c47..84a1a7ab 100644 --- a/docs/re/structures/voice-region-starts-late.md +++ b/docs/re/structures/voice-region-starts-late.md @@ -50,36 +50,43 @@ stable. The stream begins there and something else ends just before it. [`../data/voice-region-start-audit.txt`](../data/voice-region-start-audit.txt): -| region | starts at a boundary | **starts mid-stream** | -|---|---|---| -| 1 chunk | 24 / 24 | 0 | -| 3 chunks | 2 | 8 / 10 | +### โœ… The real population (2026-08-30, corrected) -๐Ÿ”ด **THIS POPULATION IS WRONG โ€” the audit run was cut short and I read a partial -file as a complete one.** The port agent counts **25** three-chunk regions where -this table says 10, and it is right to say both numbers cannot describe the same -set. The committed -[`../data/voice-region-start-audit.txt`](../data/voice-region-start-audit.txt) ends -mid-list at `S11A` with **no summary line** โ€” the program never printed its totals, -which is exactly the tell I should have checked and did not. +The number this page first published โ€” *"8 of 10 three-chunk regions start +mid-stream"* โ€” was **not a count**. The audit that produced it was cut short, the +committed table ends mid-list with no summary line, and I read a partial file as a +complete one. The port agent's count of **25** was right. -**So "8 of 10" is a ratio over an unknown fraction of the population.** What is -*not* affected: the mechanism, the `ADV` clip verified against the decoder, and the -fix's own sweep, which ran to completion and printed its totals (78 / 17 / 0 / 9). -โš ๏ธ But the sentence "the defect is specific to the multichannel regions" rested on -this table and is now **unsupported** โ€” it may still be true; it is not shown here. +Redone as a census that prints its population, coverage and skips together +([`../data/voice-region-chunk-census.txt`](../data/voice-region-chunk-census.txt)): -๐Ÿ“Œ This is the same trap the port hit in a `while read` loop the same day (`cargo -run` eating stdin, halving the sample silently) and the one this corpus keeps -paying for: **a silently reduced sample presenting as a complete one.** The defence -that would have caught both is stating population and coverage in the same -sentence, and refusing to read a table whose summary line is missing. +``` +POPULATION: 104 movies in the manifest +COVERAGE: 95 resolved and read, 9 unresolved, 0 unreadable (104 accounted for) + 1 chunk(s): 70 region(s) + 3 chunk(s): 25 region(s) +``` -โš ๏ธ **The audit's per-movie packet number is an UPPER BOUND, not the clip.** Its -stopping rule is "step back until the chunk *count* changes", and `to_xma_riffs` -absorbs a few packets of the previous asset into the first chunk before that -happens โ€” it reports **243** for `ADV` where the decoder-verified answer is **238**. -Only `ADV` has external ground truth, so only `ADV`'s clip is exact. +Cross-referenced against the fix's own sweep, which also ran to completion +(78 unchanged + 17 fixed + 9 skipped = 104): + +| | | +|---|---| +| regions the fix changed | **17** | +| of those, three-chunk | **17 โ€” all of them** | +| of those, one-chunk | **0** | +| three-chunk regions **not** affected | **8** โ€” `S02A S05A S07B S11A S12A S12B S13B S15B` | + +โœ… **So "the defect is specific to the multichannel regions" survives, and now has +complete populations on both sides**: every affected region has three chunks, and +not one of the 70 single-chunk regions was touched. โš ๏ธ **But it is not true that +every three-chunk region was affected** โ€” 8 of the 25 were already starting at a +boundary, which is what the 1.5 MB cap predicts, since a region only trips the +filter if its span exceeds it. + +๐Ÿ“Œ The original "8 of 10" was wrong in its denominator and coincidentally shares a +digit with the 8 that are *unaffected*. Recorded because a number that survives +into a later document by resembling the right answer is the worst kind. ## What this means for anyone consuming a voice region