rg3d_sound/decoder/
wav.rs1use crate::{buffer::DataSource, error::SoundError};
2use hound::WavReader;
3use std::{
4 fmt::{Debug, Formatter},
5 io::{Read, Seek, SeekFrom},
6 sync::{Arc, Mutex},
7 time::Duration,
8};
9
10pub(in crate) struct WavDecoder {
12 reader: WavReader<DataSource>,
13}
14
15impl Debug for WavDecoder {
16 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
17 write!(f, "WavDecoder")
18 }
19}
20
21#[derive(Clone)]
22struct WrappedDataSource {
23 data_source: Arc<Mutex<DataSource>>,
24}
25
26impl WrappedDataSource {
27 fn into_inner(self) -> DataSource {
28 Arc::try_unwrap(self.data_source)
29 .unwrap()
30 .into_inner()
31 .unwrap()
32 }
33}
34
35impl Read for WrappedDataSource {
36 fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
37 self.data_source.lock().unwrap().read(buf)
38 }
39}
40
41impl Seek for WrappedDataSource {
42 fn seek(&mut self, pos: SeekFrom) -> Result<u64, std::io::Error> {
43 self.data_source.lock().unwrap().seek(pos)
44 }
45}
46
47impl WavDecoder {
48 pub fn new(mut source: DataSource) -> Result<Self, DataSource> {
49 let pos = source.seek(SeekFrom::Current(0)).unwrap();
50 let mut wrapped_source = WrappedDataSource {
51 data_source: Arc::new(Mutex::new(source)),
52 };
53
54 let reader = match WavReader::new(wrapped_source.clone()) {
55 Ok(old_reader) => {
56 drop(old_reader);
57 wrapped_source.seek(SeekFrom::Start(pos)).unwrap();
61 WavReader::new(wrapped_source.into_inner()).unwrap()
62 }
63 Err(_) => {
64 wrapped_source.seek(SeekFrom::Start(pos)).unwrap();
65 return Err(wrapped_source.into_inner());
66 }
67 };
68
69 Ok(Self { reader })
70 }
71
72 pub fn rewind(&mut self) -> Result<(), SoundError> {
73 self.reader.seek(0)?;
74 Ok(())
75 }
76
77 pub fn time_seek(&mut self, location: Duration) {
78 let _ = self
79 .reader
80 .seek((location.as_secs_f64() * self.reader.spec().sample_rate as f64) as u32);
81 }
82
83 pub fn duration(&self) -> Option<Duration> {
84 Some(Duration::from_secs_f32(
85 self.reader.duration() as f32 / self.reader.spec().sample_rate as f32,
86 ))
87 }
88
89 pub fn channel_count(&self) -> usize {
90 self.reader.spec().channels as usize
91 }
92
93 pub fn sample_rate(&self) -> usize {
94 self.reader.spec().sample_rate as usize
95 }
96}
97
98impl Iterator for WavDecoder {
99 type Item = f32;
100
101 #[inline]
102 fn next(&mut self) -> Option<Self::Item> {
103 let spec = self.reader.spec();
104 match (spec.bits_per_sample, spec.sample_format) {
105 (8, hound::SampleFormat::Int) => self
106 .reader
107 .samples::<i8>()
108 .next()
109 .and_then(|s| s.ok().map(|s| s as f32 / i8::MAX as f32)),
110 (16, hound::SampleFormat::Int) => self
111 .reader
112 .samples::<i16>()
113 .next()
114 .and_then(|s| s.ok().map(|s| s as f32 / i16::MAX as f32)),
115 (24, hound::SampleFormat::Int) => self
116 .reader
117 .samples::<i32>()
118 .next()
119 .and_then(|s| s.ok().map(|s| s as f32 / 0x7fffff as f32)),
120 (32, hound::SampleFormat::Int) => self
121 .reader
122 .samples::<i32>()
123 .next()
124 .and_then(|s| s.ok().map(|s| s as f32 / i32::MAX as f32)),
125 (32, hound::SampleFormat::Float) => {
126 self.reader.samples::<f32>().next().and_then(|s| s.ok())
127 }
128 _ => None,
129 }
130 }
131}