use crate::signal::common::{FormatDecoder, INVALID_SAMPLE, sign_extend};
use crate::{Result, Sample};
use std::io::BufRead;
#[derive(Debug, Clone)]
pub struct Format212Decoder {
buffer: Option<u16>,
is_second: bool,
}
impl Default for Format212Decoder {
fn default() -> Self {
Self::new()
}
}
impl Format212Decoder {
#[must_use]
pub const fn new() -> Self {
Self {
buffer: None,
is_second: false,
}
}
}
impl FormatDecoder for Format212Decoder {
fn decode_buf(&mut self, reader: &mut dyn BufRead, output: &mut [Sample]) -> Result<usize> {
let mut count = 0;
for sample in output.iter_mut() {
if self.is_second {
let mut buf = [0u8; 1];
match reader.read_exact(&mut buf) {
Ok(()) => {
let Some(word) = self.buffer else {
self.is_second = false;
continue;
};
let high_bits = (word >> 12) & 0x0F;
let low_bits = u16::from(buf[0]);
let raw_value = (high_bits << 8) | low_bits;
let value = sign_extend(u32::from(raw_value), 12);
if value == (-1 << 11) {
*sample = INVALID_SAMPLE;
} else {
*sample = value;
}
self.buffer = None;
self.is_second = false;
count += 1;
}
Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
self.buffer = None;
self.is_second = false;
break;
}
Err(e) => return Err(e.into()),
}
} else {
let mut buf = [0u8; 2];
match reader.read_exact(&mut buf) {
Ok(()) => {
let word = u16::from_le_bytes(buf);
let value = sign_extend(u32::from(word & 0x0FFF), 12);
if value == (-1 << 11) {
*sample = INVALID_SAMPLE;
} else {
*sample = value;
}
self.buffer = Some(word);
self.is_second = true;
count += 1;
}
Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
break;
}
Err(e) => return Err(e.into()),
}
}
}
Ok(count)
}
fn reset(&mut self) {
self.buffer = None;
self.is_second = false;
}
fn bytes_per_sample(&self) -> Option<usize> {
None
}
fn bytes_per_frame(&self, num_signals: usize) -> Option<usize> {
Some((num_signals * 3).div_ceil(2))
}
}