//! 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}"), } } }