mod frame;
pub use frame::*;
use super::CodecType;
use byteorder::{LittleEndian, ReadBytesExt};
use std::{
fmt::Debug,
io::{Read, Result as IoResult},
mem,
};
/// Marker and state for decoding framed input files.
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub enum Container {
/// Raw, unframed input.
Raw,
/// Framed input, beginning with a JSON header.
///
/// Frames have the form `{ len: i16, payload: [u8; len]}`.
Dca {
/// Byte index of the first frame after the JSON header.
first_frame: usize,
},
}
impl Container {
/// Tries to read the header of the next frame from an input stream.
pub fn next_frame_length(
&mut self,
mut reader: impl Read,
input: CodecType,
) -> IoResult {
use Container::*;
match self {
Raw => Ok(Frame {
header_len: 0,
frame_len: input.sample_len(),
}),
Dca { .. } => reader.read_i16::().map(|frame_len| Frame {
header_len: mem::size_of::(),
frame_len: frame_len.max(0) as usize,
}),
}
}
/// Tries to seek on an input directly using sample length, if the input
/// is unframed.
pub fn try_seek_trivial(&self, input: CodecType) -> Option {
use Container::*;
match self {
Raw => Some(input.sample_len()),
_ => None,
}
}
/// Returns the byte index of the first frame containing audio payload data.
pub fn input_start(&self) -> usize {
use Container::*;
match self {
Raw => 0,
Dca { first_frame } => *first_frame,
}
}
}