use blip25_mbe::ambe_plus2_wire::dequantize::{DecoderState, Decoded, decode_to_params};
use blip25_mbe::ambe_plus2_wire::frame::{deinterleave, encode_frame, interleave, DIBITS_PER_FRAME};
use blip25_mbe::ambe_plus2_wire::priority::{prioritize, AMBE_B_COUNT};
fn pack_dibits(dibits: &[u8; DIBITS_PER_FRAME]) -> [u8; 9] {
let mut out = [0u8; 9];
let mut bit = 0;
for &d in dibits {
for pos in (0..2).rev() {
let b = (d >> pos) & 1;
out[bit / 8] |= b << (7 - (bit % 8));
bit += 1;
}
}
out
}
fn unpack_dibits(bytes: &[u8; 9]) -> [u8; DIBITS_PER_FRAME] {
let mut out = [0u8; DIBITS_PER_FRAME];
let mut bit = 0;
for slot in out.iter_mut() {
let mut d = 0u8;
for _ in 0..2 {
let b = (bytes[bit / 8] >> (7 - (bit % 8))) & 1;
d = (d << 1) | b;
bit += 1;
}
*slot = d;
}
out
}
fn inject_errors_in_c0(bytes: [u8; 9], n_errors: u32) -> [u8; 9] {
let dibits = unpack_dibits(&bytes);
let mut codewords = deinterleave(&dibits);
let flip_mask: u32 = (1u32 << n_errors) - 1;
codewords[0] ^= flip_mask;
let new_dibits = interleave(&codewords);
pack_dibits(&new_dibits)
}
fn main() {
let mut b = [0u16; AMBE_B_COUNT];
b[0] = 60; b[1] = 0; b[2] = 16; let info = prioritize(&b);
let mut _dec = DecoderState::new();
if !matches!(decode_to_params(&info, &mut _dec), Ok(Decoded::Voice(_))) {
eprintln!("clean probe frame failed to decode as voice");
std::process::exit(1);
}
let dibits = encode_frame(&info);
let clean = pack_dibits(&dibits);
let mut out = Vec::with_capacity(100 * 9);
for i in 0..100 {
let frame = if i == 50 { inject_errors_in_c0(clean, 4) }
else if i == 70 { inject_errors_in_c0(clean, 2) }
else if i == 90 { inject_errors_in_c0(clean, 3) }
else { clean };
out.extend_from_slice(&frame);
}
let binary = std::env::args().any(|a| a == "--binary");
if binary {
use std::io::Write;
std::io::stdout().write_all(&out).unwrap();
} else {
for chunk in out.chunks_exact(9) {
let hex: String = chunk.iter().map(|b| format!("{:02x}", b)).collect();
println!("{}", hex);
}
}
eprintln!("Wrote 100 frames; errors injected at indices 50 (4-err), 70 (2-err), 90 (3-err)");
}