1use crate::buffer::SampleBuffer;
6use rill_core::prelude::Sample;
7
8#[derive(Debug)]
10pub enum WavError {
11 Io(std::io::Error),
12 Hound(String),
13 Format(String),
14}
15
16impl std::fmt::Display for WavError {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 WavError::Io(e) => write!(f, "IO error: {}", e),
20 WavError::Hound(s) => write!(f, "WAV decode error: {}", s),
21 WavError::Format(s) => write!(f, "Invalid WAV: {}", s),
22 }
23 }
24}
25
26impl std::error::Error for WavError {}
27
28impl From<std::io::Error> for WavError {
29 fn from(e: std::io::Error) -> Self {
30 WavError::Io(e)
31 }
32}
33
34impl From<hound::Error> for WavError {
35 fn from(e: hound::Error) -> Self {
36 WavError::Hound(e.to_string())
37 }
38}
39
40pub fn load_wav(path: &str) -> Result<SampleBuffer<Sample>, WavError> {
42 let mut reader = hound::WavReader::open(path)?;
43 let spec = reader.spec();
44
45 let channels = spec.channels as u16;
46 let sample_rate = spec.sample_rate as f32;
47 let bits_per_sample = spec.bits_per_sample;
48
49 if bits_per_sample != 16 {
50 return Err(WavError::Format(format!(
51 "Only 16-bit PCM supported, got {}-bit",
52 bits_per_sample
53 )));
54 }
55
56 if channels != 1 && channels != 2 {
57 return Err(WavError::Format(format!(
58 "Only mono/stereo supported, got {} channels",
59 channels
60 )));
61 }
62
63 let samples: Vec<i16> = reader.samples::<i16>().collect::<Result<Vec<_>, _>>().map_err(|e| {
64 WavError::Format(format!("Sample read error: {}", e))
65 })?;
66
67 let name = path.rsplit('/').next().unwrap_or(path);
68
69 if channels == 1 {
70 let data: Vec<Sample> = samples.into_iter().map(|s| s as Sample / 32768.0).collect();
71 Ok(SampleBuffer::mono(data, sample_rate, name))
72 } else {
73 let mut left = Vec::with_capacity(samples.len() / 2);
74 let mut right = Vec::with_capacity(samples.len() / 2);
75 for chunk in samples.chunks(2) {
76 left.push(chunk[0] as Sample / 32768.0);
77 right.push(chunk[1] as Sample / 32768.0);
78 }
79 Ok(SampleBuffer::stereo(left, right, sample_rate, name))
80 }
81}