use rusty_opus::OpusDecoder;
use std::fs::File; use std::io::Read;
fn main() {
let a: Vec<String> = std::env::args().collect();
let (rate, ch, drop_every): (i32,usize,usize)=(a[1].parse().unwrap(),a[2].parse().unwrap(),a[4].parse().unwrap());
let mut data=Vec::new(); File::open(&a[3]).unwrap().read_to_end(&mut data).unwrap();
let mut pkts: Vec<Vec<u8>> = Vec::new();
let mut pos=0; while pos+8<=data.len() { let ln=u32::from_be_bytes([data[pos],data[pos+1],data[pos+2],data[pos+3]]) as usize; pos+=8; pkts.push(data[pos..pos+ln].to_vec()); pos+=ln; }
let fsz=(rate as usize/50)*1;
let mut dec=OpusDecoder::new(rate,ch).unwrap();
let mut out=vec![0f32; fsz*ch];
let (mut fec_e, mut fec_n, mut fec_recovered)=(0f64,0usize,0usize);
let mut i=0usize;
while i<pkts.len() {
let drop = i % drop_every == (drop_every-1);
if drop {
if i+1<pkts.len() {
dec.decode_fec(&pkts[i+1], fsz, &mut out).unwrap();
let e: f64 = out[..fsz*ch].iter().map(|&v|(v as f64)*(v as f64)).sum();
fec_e+=e; fec_n+=1; if e>0.01 { fec_recovered+=1; }
}
if i+1<pkts.len() { dec.decode(&pkts[i+1], fsz, &mut out).unwrap(); }
i+=2;
} else {
dec.decode(&pkts[i], fsz, &mut out).unwrap();
i+=1;
}
}
println!("fec_frames={fec_n} recovered_with_audio={fec_recovered} mean_fec_energy={:.3}", fec_e/fec_n.max(1) as f64);
}