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>
67 lines
2.9 KiB
Rust
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}"),
|
|
}
|
|
}
|
|
}
|