mod read;
mod write;
use std::fs;
use std::io;
use super::{audio, errors, utils, Result};
pub use read::ReadBuffer;
pub use write::WriteBuffer;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum SampleFormat {
U8,
U16,
U24,
U32,
S8,
S16,
S24,
S32,
F32,
}
pub trait Sample: Sized + Copy {
fn read<R: ReadBuffer>(reader: &mut R, sample_format: SampleFormat, bits: u16) -> Result<Self>;
fn write<W: WriteBuffer>(self, writer: &mut W, bits: u16) -> Result<()>;
}
impl Sample for i8 {
fn read<R: ReadBuffer>(reader: &mut R, sample_format: SampleFormat, bits: u16) -> Result<i8> {
if sample_format == SampleFormat::F32 {
return errors::unsupported_error::<i8>("Invalid sample format");
}
match bits {
8 => Ok(reader.read_u8().map(utils::signed_from_u8)?),
_ => errors::unsupported_error::<i8>(""),
}
}
fn write<W: WriteBuffer>(self, writer: &mut W, bits: u16) -> Result<()> {
match bits {
8 => Ok(writer.write_u8(utils::u8_from_signed(self))?),
16 => Ok(writer.write_le_i16(self as i16)?),
24 => Ok(writer.write_le_i24(self as i32)?),
32 => Ok(writer.write_le_i32(self as i32)?),
_ => errors::unsupported_error::<()>(""),
}
}
}
impl Sample for i16 {
fn read<R: ReadBuffer>(reader: &mut R, sample_format: SampleFormat, bits: u16) -> Result<i16> {
if sample_format == SampleFormat::F32 {
return errors::unsupported_error::<i16>("Invalid sample format");
}
match bits {
8 => Ok(reader
.read_u8()
.map(utils::signed_from_u8)
.map(|x| x as i16)?),
16 => Ok(reader.read_le_i16()?),
_ => errors::unsupported_error::<i16>(""),
}
}
fn write<W: WriteBuffer>(self, writer: &mut W, bits: u16) -> Result<()> {
match bits {
8 => Ok(writer.write_u8(utils::u8_from_signed(utils::narrow_to_i8(self as i32)?))?),
16 => Ok(writer.write_le_i16(self)?),
24 => Ok(writer.write_le_i24(self as i32)?),
32 => Ok(writer.write_le_i32(self as i32)?),
_ => errors::unsupported_error::<()>(""),
}
}
}
impl Sample for i32 {
fn read<R: ReadBuffer>(reader: &mut R, sample_format: SampleFormat, bits: u16) -> Result<i32> {
if sample_format == SampleFormat::F32 {
return errors::unsupported_error::<i32>("Invalid sample format");
}
match bits {
8 => Ok(reader
.read_u8()
.map(utils::signed_from_u8)
.map(|x| x as i32)?),
16 => Ok(reader.read_le_i16().map(|x| x as i32)?),
24 => Ok(reader.read_le_i24()?),
32 => Ok(reader.read_le_i32()?),
_ => errors::unsupported_error::<i32>(""),
}
}
fn write<W: WriteBuffer>(self, writer: &mut W, bits: u16) -> Result<()> {
match bits {
8 => Ok(writer.write_u8(utils::u8_from_signed(utils::narrow_to_i8(self as i32)?))?),
16 => Ok(writer.write_le_i16(utils::narrow_to_i16(self)?)?),
24 => Ok(writer.write_le_i24(utils::narrow_to_i24(self)?)?),
32 => Ok(writer.write_le_i32(self as i32)?),
_ => errors::unsupported_error::<()>(""),
}
}
}
impl Sample for f32 {
fn read<R: ReadBuffer>(reader: &mut R, sample_format: SampleFormat, bits: u16) -> Result<f32> {
if sample_format == SampleFormat::F32 {
match bits {
32 => Ok(reader.read_le_f32()?),
_ => errors::unsupported_error::<f32>(""),
}
} else {
match bits {
8 => Ok(reader
.read_u8()
.map(utils::signed_from_u8)
.map(|x| x as f32)?),
16 => Ok(reader.read_le_i16().map(|x| x as f32)?),
24 => Ok(reader.read_le_i24()? as f32),
_ => errors::unsupported_error::<f32>(""),
}
}
}
fn write<W: WriteBuffer>(self, writer: &mut W, bits: u16) -> Result<()> {
match bits {
32 => Ok(writer.write_le_f32(self)?),
_ => errors::unsupported_error::<()>(""),
}
}
}
pub type MediaSource = io::BufReader<fs::File>;
pub trait AudioReader {
fn read_header(&mut self) -> Result<audio::AudioInfo>;
fn buffer(&mut self) -> &mut MediaSource;
}
pub trait AudioSamplesIterator<S: Sample> {
fn next(&mut self) -> Option<Result<S>>;
}
impl<'r, S: Sample> Iterator for dyn AudioSamplesIterator<S> + 'r {
type Item = Result<S>;
fn next(&mut self) -> Option<Result<S>> {
self.next()
}
}