1use std::{
2 collections::HashMap,
3 fs::File,
4 io::{BufReader, Read},
5};
6
7use reqwest::blocking::Response;
8
9const LEN_CHUNK_DESCRIPTOR: usize = 4;
11const LEN_WAVE_FLAG: usize = 4;
12const LEN_FMT_SUB_CHUNK: usize = 4;
13const LEN_DATA_SUB_CHUNK: usize = 4;
14
15const RIFF: &str = "RIFF";
17const WAVE: &str = "WAVE";
18const FMT_: &str = "fmt ";
19const DATA: &str = "data";
20
21#[derive(Debug)]
22enum WavReader {
23 FileReader(BufReader<File>),
24 ResponseReader(BufReader<Response>),
25}
26
27#[derive(Debug, Default)]
28pub struct Wav {
29 chunk_descriptor: String,
30 chunk_size: u64,
31 wave_flag: String,
32 fmt_sub_chunk: String,
33 sub_chunk1_size: u64,
34 audio_format: i32,
35 num_channels: u32,
36 sample_rate: u64,
37 byte_rate: u64,
38 block_align: i32,
39 bits_per_sample: u32,
40 sub_chunk2_size: u32,
41 data: String,
42 length: u32,
43 reader: Option<WavReader>,
44 sample_data: HashMap<u32, Vec<f64>>,
45 json_width: u32,
46}
47
48impl Wav {
49 pub fn new(path: &str) -> Self {
72 let reader;
73 if path.starts_with("http") {
74 let resp = reqwest::blocking::get(path).unwrap();
75 reader = Some(WavReader::ResponseReader(BufReader::new(resp)));
76 } else {
77 let file = File::open(path).unwrap();
78 reader = Some(WavReader::FileReader(BufReader::new(file)));
79 }
80
81 Self {
82 reader,
83 ..Default::default()
84 }
85 }
86
87 pub fn set_json_width(mut self, width: u32) -> Self {
89 self.json_width = width;
90
91 self
92 }
93
94 pub fn decode(&mut self) -> Vec<f64> {
96 let mut buf = vec![0u8; 2];
97 self.chunk_descriptor = self.read_string(LEN_CHUNK_DESCRIPTOR);
98 if !self.chunk_descriptor.eq(RIFF) {
99 println!("Not standard format!")
100 }
101 self.chunk_size = self.read_long();
102 self.wave_flag = self.read_string(LEN_WAVE_FLAG);
103 if !self.wave_flag.eq(WAVE) {
104 println!("Not standard format!")
105 }
106 self.fmt_sub_chunk = self.read_string(LEN_FMT_SUB_CHUNK);
107 if !self.fmt_sub_chunk.eq(FMT_) {
108 println!("Not standard format!")
109 }
110 self.sub_chunk1_size = self.read_long();
111 self.audio_format = self.read_int(&mut buf);
112 self.num_channels = self.read_int(&mut buf) as u32;
113 self.sample_rate = self.read_long();
114 self.byte_rate = self.read_long();
115 self.block_align = self.read_int(&mut buf);
116 self.bits_per_sample = self.read_int(&mut buf) as u32;
117
118 self.data = self.read_string(LEN_DATA_SUB_CHUNK);
119 if !self.data.eq(DATA) {
120 println!("Not standard format!")
121 }
122 self.sub_chunk2_size = self.read_long() as u32;
123 self.length =
124 (self.sub_chunk2_size / (self.bits_per_sample / 8) / self.num_channels) as u32;
125
126 self.read_data(self.length);
127
128 let mut result_data: Vec<f64> = Vec::new();
129
130 let len = self.sample_data.len() as u32;
131 match len {
132 1 => {
133 result_data = self.sample_data.get(&0).unwrap().to_vec();
134 }
135 _ => {
136 let mut max4 = 0;
137 for i in 0..len {
138 if i <= len - 2 {
139 max4 = self
140 .sample_data
141 .get(&i)
142 .unwrap()
143 .len()
144 .max(self.sample_data.get(&(i + 1)).unwrap().len())
145 }
146 }
147 for i in 0..max4 {
148 for j in 0..len {
149 if self.sample_data.get(&j).unwrap().len() >= i {
150 let val = self.sample_data.get(&j).unwrap().get(i).unwrap();
151 result_data.push((*val * 100.0).round() / 100.0);
152 }
153 }
154 }
155 }
156 }
157
158 result_data
159 }
160
161 fn read_data(&mut self, length: u32) {
163 let size;
164 if length <= self.json_width {
165 size = 1;
166 } else {
167 size = length / self.json_width;
168 }
169
170 for i in 0..self.num_channels {
171 self.sample_data.insert(i, Vec::new());
172 }
173
174 let buf: &mut Vec<u8> = &mut vec![0u8; 2];
175
176 let mut sample_sum: i64 = 0;
177 let mut i = 0;
178 while i < length {
179 let mut n = 0;
180 while n < self.num_channels {
181 match self.bits_per_sample {
182 8 => {
183 if i == length - 1 {
184 self.handle8bit(n, sample_sum, size);
185 } else {
186 let mut buf = vec![0u8; 1];
187 if let Some(wav_reader) = self.reader.as_mut() {
188 let mut handle_reader = |reader: &mut dyn Read| {
189 reader.read(&mut buf).unwrap();
190 };
191 match wav_reader {
192 WavReader::FileReader(reader) => handle_reader(reader),
193 WavReader::ResponseReader(reader) => handle_reader(reader),
194 }
195 }
196 if i != 0 && (i % size) == 0 {
197 self.handle8bit(n, sample_sum, size);
198 sample_sum = 0;
199 } else {
200 sample_sum += (buf[0] as i64).pow(2);
201 }
202 }
203 }
204 16 => {
205 if i == length - 1 {
206 self.handle16bit(n, sample_sum, size);
207 } else {
208 let val = self.read_int(buf) as i64;
209 if i != 0 && (i % size) == 0 {
210 self.handle16bit(n, sample_sum, size);
211 sample_sum = 0;
212 } else {
213 sample_sum += val.pow(2);
214 }
215 }
216 }
217 _ => {}
218 }
219
220 n += 1;
221 }
222 i += 1;
223 }
224 }
225
226 fn handle8bit(&mut self, key: u32, sample_sum: i64, size: u32) {
227 self.handle_bit(key, sample_sum, size, 128f32);
228 }
229
230 fn handle16bit(&mut self, key: u32, sample_sum: i64, size: u32) {
231 self.handle_bit(key, sample_sum, size, 32768f32);
232 }
233
234 fn handle_bit(&mut self, key: u32, sample_sum: i64, size: u32, scope: f32) {
243 let sample_arr = self.sample_data.get_mut(&key).unwrap();
244 let data = cal_rms(sample_sum as f32 / scope, size);
245 sample_arr.push(data);
246 }
247
248 fn read_string(&mut self, len: usize) -> String {
249 let mut buf = vec![0u8; len];
250 if let Some(wav_reader) = self.reader.as_mut() {
251 let mut handle_reader = |reader: &mut dyn Read| {
252 reader.read(&mut buf).unwrap();
253 };
254 match wav_reader {
255 WavReader::FileReader(reader) => handle_reader(reader),
256 WavReader::ResponseReader(reader) => handle_reader(reader),
257 }
258 }
259 String::from_utf8(buf).unwrap()
260 }
261
262 fn read_long(&mut self) -> u64 {
263 let mut buffer = [0u64; 4];
264 let mut i = 0;
265 while i < 4 {
266 let mut buf = vec![0u8; 1];
267 if let Some(wav_reader) = self.reader.as_mut() {
268 let mut handle_reader = |reader: &mut dyn Read| {
269 reader.read(&mut buf).unwrap();
270 };
271 match wav_reader {
272 WavReader::FileReader(reader) => handle_reader(reader),
273 WavReader::ResponseReader(reader) => handle_reader(reader),
274 }
275 }
276 buffer[i] = buf[0] as u64;
277 i += 1;
278 }
279 buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24)
280 }
281
282 fn read_int(&mut self, buf: &mut Vec<u8>) -> i32 {
283 if let Some(reader_type) = self.reader.as_mut() {
284 let mut handle_reader = |reader: &mut dyn Read| {
285 reader.read(buf).unwrap();
286 };
287 match reader_type {
288 WavReader::FileReader(reader) => handle_reader(reader),
289 WavReader::ResponseReader(reader) => handle_reader(reader),
290 }
291 }
292 buf[0] as i32 | ((buf[1] as i8) as i32) << 8
293 }
294}
295
296fn cal_rms(sample_sum: f32, size: u32) -> f64 {
298 (sample_sum / size as f32).sqrt() as f64
299}
300
301#[cfg(test)]
302mod tests {
303 use super::*;
304
305 #[test]
306 fn decode() {
307 let mut wav = Wav::new("examples/sample-15s.wav").set_json_width(3000);
308 let result_data = wav.decode();
309 println!("{:?}", result_data)
310 }
311}