summaryrefslogtreecommitdiff
path: root/src/output/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/output/mod.rs')
-rw-r--r--src/output/mod.rs68
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;