Files
Sylpheed/crates/sylpheed-export/examples/bank_chunks.rs
sim cc9392bde4 test: one disc resolver, no machine-specific defaults, all three corpora in the container
Finishes #16 in the three places its earlier remedies missed.

`tests/`: the last four local `disc_root()` copies now use `tests/common`, and
with them goes the one real hardcoded fallback — `ui_keyframe_record_disc.rs`
fell back to an absolute path on one machine, which made `unset SYLPHEED_DISC`
a no-op there. Control: with the corpus absent that suite now finishes in 0.00s
instead of 57.55s, so it skips rather than finding a disc of its own.

`examples/`: seventeen examples defaulted to `/disc`, the mount point inside the
CI container. Redundant there — `docker/ci/run` sets `SYLPHEED_DISC=/disc` — and
wrong everywhere else, where a missing corpus turned into a file-not-found
against a path that has never existed on the host. They now name the variable to
set, like the other hundred examples already did.

`docker/ci/run`: mount `$SYLPHEED_RES3D` and `$SYLPHEED_ISO` alongside the disc.
Only the disc was mounted, so an in-container run sat out the res3d and iso
suites while looking like a full one — the defect this issue is about, in the
runner itself.

Measured in the container on this desktop with all three corpora present:
45 suites / 377 passed / 0 failed / 14 ignored, and `sylpheed-corpus-report.txt`
now reports PRESENT for all three rather than for the disc alone.

Refs #16.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 22:18:59 +02:00

67 lines
2.9 KiB
Rust

//! Throwaway probe: what are a music bank's sub-waves, decoded and timed?
//!
//! `export_bgm` sums every sub-wave `media` returns and scales by 1/n. If one of
//! them is not music, the divisor is wrong and every real stem is attenuated for
//! nothing -- the same defect already found and fixed in `export_voice`.
use std::process::Command;
use sylpheed_formats::media;
fn main() {
let disc =
std::env::var("SYLPHEED_DISC").expect("set SYLPHEED_DISC to the extracted disc root");
let src = media::DirectorySource::new(&disc);
for bank in ["BGM_103.slb", "BGM_102.slb", "BGM_001.slb"] {
match media::sound_bank_riffs(&src, bank) {
Ok(riffs) => {
println!("{bank}: {} sub-wave(s)", riffs.len());
for (i, r) in riffs.iter().enumerate() {
let p = std::env::temp_dir().join(format!("bk_{i}.xma.wav"));
std::fs::write(&p, r).unwrap();
let w = std::env::temp_dir().join(format!("bk_{i}.wav"));
let _ = Command::new("ffmpeg")
.args(["-hide_banner", "-loglevel", "error", "-y", "-i"])
.arg(&p)
.arg(&w)
.output();
let out = Command::new("ffmpeg")
.args(["-hide_banner", "-v", "info", "-i"])
.arg(&w)
.args(["-af", "astats=measure_perchannel=none", "-f", "null", "-"])
.output()
.unwrap();
let t = String::from_utf8_lossy(&out.stderr).into_owned();
let get = |k: &str| {
t.lines()
.find_map(|l| l.split_once(k).map(|x| x.1.trim().to_string()))
.unwrap_or_else(|| "?".into())
};
let dur = Command::new("ffprobe")
.args([
"-v",
"error",
"-show_entries",
"format=duration",
"-of",
"csv=p=0",
])
.arg(&w)
.output()
.ok()
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
.unwrap_or_default();
println!(
" sub-wave {i}: {:>9} B -> {:>10} s peak {:>10} rms {}",
r.len(),
dur,
get("Peak level dB:"),
get("RMS level dB:")
);
let _ = std::fs::remove_file(&p);
let _ = std::fs::remove_file(&w);
}
}
Err(e) => println!("{bank}: {e}"),
}
}
}