use std::fs::File;
use std::io::BufWriter;
use std::marker::PhantomData;
use std::path::Path;
use audio_samples::AudioSamples;
use audio_samples::traits::StandardSample;
use audio_samples_io::WriteSeek;
use audio_samples_io::error::AudioIOError;
use audio_samples_io::traits::AudioStreamWrite;
use audio_samples_io::traits::AudioStreamWriter;
use audio_samples_io::wav::StreamedWavWriter;
use crate::traits::AudioSink;
pub struct WavFileSink<W: WriteSeek, T: StandardSample> {
inner: StreamedWavWriter<W>,
_marker: PhantomData<T>,
}
impl<W: WriteSeek, T: StandardSample> WavFileSink<W, T> {
pub fn new_i16(writer: W, channels: u16, sample_rate: u32) -> Result<Self, AudioIOError> {
Ok(Self {
inner: StreamedWavWriter::new_i16(writer, channels, sample_rate)?,
_marker: PhantomData,
})
}
pub fn new_i24(writer: W, channels: u16, sample_rate: u32) -> Result<Self, AudioIOError> {
Ok(Self {
inner: StreamedWavWriter::new_i24(writer, channels, sample_rate)?,
_marker: PhantomData,
})
}
pub fn new_i32(writer: W, channels: u16, sample_rate: u32) -> Result<Self, AudioIOError> {
Ok(Self {
inner: StreamedWavWriter::new_i32(writer, channels, sample_rate)?,
_marker: PhantomData,
})
}
pub fn new_f32(writer: W, channels: u16, sample_rate: u32) -> Result<Self, AudioIOError> {
Ok(Self {
inner: StreamedWavWriter::new_f32(writer, channels, sample_rate)?,
_marker: PhantomData,
})
}
pub fn new_f64(writer: W, channels: u16, sample_rate: u32) -> Result<Self, AudioIOError> {
Ok(Self {
inner: StreamedWavWriter::new_f64(writer, channels, sample_rate)?,
_marker: PhantomData,
})
}
pub fn frames_written(&self) -> usize {
self.inner.frames_written()
}
}
impl<T: StandardSample + 'static> WavFileSink<BufWriter<File>, T> {
pub fn create<P: AsRef<Path>>(
path: P,
channels: u16,
sample_rate: u32,
) -> Result<Self, AudioIOError>
where
T: audio_samples::ConvertTo<f32>,
{
let writer = BufWriter::new(File::create(path)?);
Self::new_f32(writer, channels, sample_rate)
}
pub fn create_typed<P: AsRef<Path>>(
path: P,
channels: u16,
sample_rate: u32,
sample_type: audio_samples_io::ValidatedSampleType,
) -> Result<Self, AudioIOError> {
let inner = audio_samples_io::create_streamed(path, channels, sample_rate, sample_type)?;
Ok(Self {
inner,
_marker: PhantomData,
})
}
}
impl<W: WriteSeek, T: StandardSample + 'static> AudioSink for WavFileSink<W, T> {
type Sample = T;
type Error = AudioIOError;
fn write_chunk(
&mut self,
chunk: &AudioSamples<'static, Self::Sample>,
) -> Result<(), Self::Error> {
self.inner.write_frames(chunk)?;
Ok(())
}
fn flush(&mut self) -> Result<(), Self::Error> {
AudioStreamWriter::flush(&mut self.inner)
}
fn finalize(mut self) -> Result<(), Self::Error> {
AudioStreamWriter::finalize(&mut self.inner)
}
}