diff options
Diffstat (limited to 'src/output/mod.rs')
-rw-r--r-- | src/output/mod.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/output/mod.rs b/src/output/mod.rs new file mode 100644 index 0000000..520a500 --- /dev/null +++ b/src/output/mod.rs @@ -0,0 +1,68 @@ +//! This file implements the interface to save waves into a file. + +use std::{ + error::Error, + fmt::{self, Display, Formatter}, + io::{self, Write}, +}; + +use super::*; + +#[derive(Debug)] +pub enum OutputError { + Io(std::io::Error), + FFMpeg(String), + EmptyWaves, +} + +impl Display for OutputError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::Io(e) => write!(f, "io: {e}"), + Self::EmptyWaves => write!(f, "empty waves"), + OutputError::FFMpeg(s) => write!(f, "FFMPEG error: {s}"), + } + } +} + +impl Error for OutputError {} + +impl From<io::Error> for OutputError { + fn from(io: io::Error) -> Self { + Self::Io(io) + } +} + +/// A type that implements this trait implements a generic function +/// for saving waves into files. +pub trait Output { + /// Save waves DATA with RATE samples per second into a file with + /// NAME. + fn save(&self, data: Wave, rate: Samples, name: &str) -> Result<(), OutputError>; +} + +/// A dummy struct to hold a generic function for saving waves. +#[derive(Default)] +pub struct PlainOutput {} + +impl Output for PlainOutput { + fn save(&self, data: Wave, _rate: Samples, name: &str) -> Result<(), OutputError> { + if data.is_empty() { + return Err(OutputError::EmptyWaves); + } + + let bytes: Vec<u8> = data.iter().flat_map(|pulse| pulse.to_le_bytes()).collect(); + + let mut file = std::fs::OpenOptions::new() + .create(true) + .write(true) + .open(name)?; + + file.write_all(&bytes)?; + + Ok(()) + } +} + +#[cfg(feature = "ffmpeg")] +pub mod ffmpeg_output; |