use std::io::{BufRead, Write};
use mcelp::{Decoder, bitstream};
fn main() -> std::io::Result<()> {
let stdin = std::io::stdin();
let stdout = std::io::stdout();
decode_stream(stdin.lock(), std::io::BufWriter::new(stdout.lock()))
}
fn decode_stream(input: impl BufRead, mut output: impl Write) -> std::io::Result<()> {
let mut decoder = Decoder::new();
for line in input.lines() {
let Some(frame) = bitstream::parse_hex_line(&line?) else {
continue;
};
if let Some(pcm) = decoder.decode(&frame) {
output.write_all(&pcm)?;
}
}
output.flush()
}
#[cfg(test)]
mod tests {
use mcelp::{Encoder, FRAME};
use super::*;
#[test]
fn stream_matches_decoder_and_skips_invalid_lines() {
let first = [0xff; FRAME];
let second = std::array::from_fn(|i| i as u8);
let mut encoder = Encoder::new();
let frames = [encoder.encode(&first), encoder.encode(&second)];
let input = format!(
"not a frame\n{}\n\n{}\ntruncated\n",
bitstream::to_hex_line(&frames[0]),
bitstream::to_hex_line(&frames[1]),
);
let mut decoder = Decoder::new();
let mut expected = Vec::new();
for frame in &frames {
if let Some(pcm) = decoder.decode(frame) {
expected.extend_from_slice(&pcm);
}
}
let mut output = Vec::new();
decode_stream(input.as_bytes(), &mut output).unwrap();
assert_eq!(output, expected);
}
}