use crate::{Result, Sample};
use std::io::BufRead;
pub const INVALID_SAMPLE: Sample = Sample::MIN;
#[derive(Debug, Clone)]
pub struct DecoderConfig {
pub initial_value: Sample,
pub samples_per_frame: usize,
pub byte_offset: u64,
}
impl Default for DecoderConfig {
fn default() -> Self {
Self {
initial_value: 0,
samples_per_frame: 1,
byte_offset: 0,
}
}
}
pub trait FormatDecoder: Send {
fn decode_buf(&mut self, reader: &mut dyn BufRead, output: &mut [Sample]) -> Result<usize>;
fn decode(&mut self, reader: &mut dyn BufRead, count: usize) -> Result<Vec<Sample>> {
let mut output = vec![0; count];
let n = self.decode_buf(reader, &mut output)?;
output.truncate(n);
Ok(output)
}
fn reset(&mut self);
fn bytes_per_sample(&self) -> Option<usize> {
None
}
fn bytes_per_frame(&self, num_signals: usize) -> Option<usize> {
self.bytes_per_sample().map(|bps| bps * num_signals)
}
fn samples<R: BufRead>(&mut self, reader: R) -> SampleIter<'_, Self, R>
where
Self: Sized,
{
SampleIter::new(self, reader)
}
}
#[inline]
#[must_use]
#[allow(clippy::cast_possible_wrap)]
pub const fn sign_extend(value: u32, bits: u32) -> i32 {
let sign_bit = 1 << (bits - 1);
if value & sign_bit != 0 {
(value | !((1 << bits) - 1)) as i32
} else {
(value & ((1 << bits) - 1)) as i32
}
}
pub struct SampleIter<'a, D, R>
where
D: FormatDecoder + ?Sized,
R: BufRead,
{
decoder: &'a mut D,
reader: R,
buffer: [Sample; 1],
done: bool,
}
impl<'a, D, R> SampleIter<'a, D, R>
where
D: FormatDecoder + ?Sized,
R: BufRead,
{
pub const fn new(decoder: &'a mut D, reader: R) -> Self {
Self {
decoder,
reader,
buffer: [0],
done: false,
}
}
}
impl<D, R> Iterator for SampleIter<'_, D, R>
where
D: FormatDecoder + ?Sized,
R: BufRead,
{
type Item = Result<Sample>;
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
match self.decoder.decode_buf(&mut self.reader, &mut self.buffer) {
Ok(0) => {
self.done = true;
None }
Ok(_) => Some(Ok(self.buffer[0])),
Err(e) => {
self.done = true;
Some(Err(e))
}
}
}
}