1use std::fs::File;
7use std::io::{Read, Seek, SeekFrom};
8
9const INVALID_FILE_SIZE: &str = "Invalid file size";
10const INVALID_CHUNK_ID: &str = "Invalid chunk id";
11const INVALID_FORMAT: &str = "Invalid format";
12const INVALID_FMT_CHUNK: &str = "Invalid fmt chunk";
13const INVALID_FMT_CHUNK_SIZE: &str = "Invalid fmt chunk size";
14const INVALID_BIT_DEPTH: &str = "Invalid bit depth";
15const INVALID_SAMPLING_RATE: &str = "Invalid sampling rate";
16const FILE_NOT_FOUND: &str = "File not found";
17const INVALID_DATA_CHUNK: &str = "Invalid data chunk";
18
19fn check_riff_chunk(file: &mut File) -> Result<(), &'static str> {
20 let mut buffer = [0; 12];
21 match file.read_exact(&mut buffer) {
22 Ok(_) => {}
23 Err(_) => return Err(INVALID_FILE_SIZE),
24 }
25
26 let chunk_id = &buffer[0..4];
27 let format = &buffer[8..12];
28 if chunk_id != b"RIFF" {
29 return Err(INVALID_CHUNK_ID);
30 } else if format != b"WAVE" {
31 return Err(INVALID_FORMAT);
32 }
33 Ok(())
34}
35
36fn check_junk_chunk(file: &mut File) -> Result<(), &'static str> {
37 let mut buffer = [0; 4];
38 match file.read_exact(&mut buffer) {
39 Ok(_) => {}
40 Err(_) => return Err(INVALID_FILE_SIZE),
41 }
42 if &buffer == b"JUNK" {
43 match file.read_exact(&mut buffer) {
45 Ok(_) => {}
46 Err(_) => return Err(INVALID_FILE_SIZE),
47 }
48 match file.seek(SeekFrom::Current(u32::from_le_bytes(buffer) as i64)) {
51 Ok(_) => {}
52 Err(_) => return Err(INVALID_FILE_SIZE),
53 }
54 }
55 Ok(())
56}
57
58fn check_fmt_chunk(file: &mut File) -> Result<(u16, u32, u16), &'static str> {
59 let mut buffer = [0; 4];
60 match file.read_exact(&mut buffer) {
61 Ok(_) => {}
62 Err(_) => return Err(INVALID_FILE_SIZE),
63 }
64 if &buffer != b"fmt " {
65 return Err(INVALID_FMT_CHUNK);
66 }
67 match file.read_exact(&mut buffer) {
68 Ok(_) => {}
69 Err(_) => return Err(INVALID_FILE_SIZE),
70 }
71
72 let channels;
73 let sampling_rate;
74 let bit_depth;
75 if buffer == [16, 0, 0, 0] {
76 let mut fmt_buffer = [0; 16];
77 match file.read_exact(&mut fmt_buffer) {
78 Ok(_) => {}
79 Err(_) => return Err(INVALID_FILE_SIZE),
80 }
81
82 channels = u16::from_le_bytes([fmt_buffer[2], fmt_buffer[3]]);
83 sampling_rate =
84 u32::from_le_bytes([fmt_buffer[4], fmt_buffer[5], fmt_buffer[6], fmt_buffer[7]]);
85 bit_depth = u16::from_le_bytes([fmt_buffer[14], fmt_buffer[15]]);
86
87 if fmt_buffer[0..2] == [1, 0] {
88 if ![8, 16, 24].contains(&bit_depth) {
89 return Err(INVALID_BIT_DEPTH);
90 }
91 } else if fmt_buffer[0..2] == [3, 0] {
92 if bit_depth != 32 {
93 return Err(INVALID_BIT_DEPTH);
94 }
95 } else {
96 return Err(INVALID_FORMAT);
97 }
98 } else {
99 return Err(INVALID_FMT_CHUNK_SIZE);
100 }
101 Ok((channels, sampling_rate, bit_depth))
102}
103
104fn check_data_chunk(file: &mut File) -> Result<Vec<u8>, &'static str> {
105 let mut buffer = [0; 4];
106 match file.read_exact(&mut buffer) {
107 Ok(_) => {}
108 Err(_) => return Err(INVALID_FILE_SIZE),
109 }
110 if &buffer != b"data" {
111 return Err(INVALID_DATA_CHUNK);
112 }
113 match file.read_exact(&mut buffer) {
114 Ok(_) => {}
115 Err(_) => return Err(INVALID_FILE_SIZE),
116 }
117 let data_size = u32::from_le_bytes(buffer);
118 let mut data = vec![0u8; data_size as usize];
120 match file.read_exact(&mut data) {
121 Ok(_) => {}
122 Err(_) => return Err(INVALID_FILE_SIZE),
123 }
124 Ok(data)
125}
126
127pub fn get_info<T>(path: T) -> Result<(u16, u32, u16), &'static str>
137where
138 T: AsRef<std::path::Path>,
139{
140 let file = File::open(path);
141 if file.is_err() {
142 return Err(FILE_NOT_FOUND);
143 }
144 let mut file = file.unwrap();
145
146 check_riff_chunk(&mut file)?;
147 check_junk_chunk(&mut file)?;
148 check_fmt_chunk(&mut file)
149}
150
151fn to_vec_i8_from_i8(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<i8> {
152 if buffer.len() % ch_cnt != 0 {
153 panic!("Invalid buffer size");
154 }
155 buffer
156 .iter()
157 .skip(channel)
158 .step_by(ch_cnt)
159 .map(|&x| (x as i16 - 128) as i8)
160 .collect()
161}
162
163pub fn load_wav_8bit<T>(path: T, sampling_rate: u32) -> Result<Vec<Vec<i8>>, &'static str>
176where
177 T: AsRef<std::path::Path>,
178{
179 let file = File::open(path);
180 if file.is_err() {
181 return Err(FILE_NOT_FOUND);
182 }
183 let mut file = file.unwrap();
184
185 check_riff_chunk(&mut file)?;
186 check_junk_chunk(&mut file)?;
187
188 let (channels, sr, bit_depth) = check_fmt_chunk(&mut file)?;
189 if sr != sampling_rate {
190 return Err(INVALID_SAMPLING_RATE);
191 }
192 let data = check_data_chunk(&mut file)?;
193
194 let channels = channels as usize;
195 let mut sampleses = Vec::with_capacity(channels);
196 match bit_depth {
197 8 => {
198 for i in 0..channels {
199 sampleses.push(to_vec_i8_from_i8(&data, i, channels));
200 }
201 Ok(sampleses)
202 }
203 _ => Err(INVALID_BIT_DEPTH),
204 }
205}
206
207fn to_vec_i16_from_i8(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<i16> {
208 if buffer.len() % ch_cnt != 0 {
209 panic!("Invalid buffer size");
210 }
211 buffer
212 .iter()
213 .skip(channel)
214 .step_by(ch_cnt)
215 .map(|&x| ((x as i16 - 128) << 8))
216 .collect()
217}
218
219fn to_vec_i16_from_i16(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<i16> {
220 if buffer.len() % (ch_cnt * 2) != 0 {
221 panic!("Invalid buffer size");
222 }
223 buffer
224 .chunks(2)
225 .skip(channel)
226 .step_by(ch_cnt)
227 .map(|x| i16::from_le_bytes([x[0], x[1]]))
228 .collect()
229}
230
231pub fn load_wav_16bit<T>(path: T, sampling_rate: u32) -> Result<Vec<Vec<i16>>, &'static str>
243where
244 T: AsRef<std::path::Path>,
245{
246 let file = File::open(path);
247 if file.is_err() {
248 return Err(FILE_NOT_FOUND);
249 }
250 let mut file = file.unwrap();
251
252 check_riff_chunk(&mut file)?;
253 check_junk_chunk(&mut file)?;
254
255 let (channels, sr, bit_depth) = check_fmt_chunk(&mut file)?;
256 if sr != sampling_rate {
257 return Err(INVALID_SAMPLING_RATE);
258 }
259 let data = check_data_chunk(&mut file)?;
260
261 let channels = channels as usize;
262 let mut sampleses = Vec::with_capacity(channels);
263 match bit_depth {
264 8 => {
265 for i in 0..channels {
266 sampleses.push(to_vec_i16_from_i8(&data, i, channels));
267 }
268 Ok(sampleses)
269 }
270 16 => {
271 for i in 0..channels {
272 sampleses.push(to_vec_i16_from_i16(&data, i, channels));
273 }
274 Ok(sampleses)
275 }
276 _ => Err(INVALID_BIT_DEPTH),
277 }
278}
279
280fn to_vec_i32_from_i8(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<i32> {
281 if buffer.len() % ch_cnt != 0 {
282 panic!("Invalid buffer size");
283 }
284 buffer
285 .iter()
286 .skip(channel)
287 .step_by(ch_cnt)
288 .map(|&x| ((x as i32 - 128) << 16))
289 .collect()
290}
291
292fn to_vec_i32_from_i16(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<i32> {
293 if buffer.len() % (ch_cnt * 2) != 0 {
294 panic!("Invalid buffer size");
295 }
296 buffer
297 .chunks(2)
298 .skip(channel)
299 .step_by(ch_cnt)
300 .map(|x| i32::from_le_bytes([x[0], x[1], 0, 0]))
301 .collect()
302}
303
304fn to_vec_i32_from_i24(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<i32> {
305 if buffer.len() % (ch_cnt * 3) != 0 {
306 panic!("Invalid buffer size");
307 }
308 buffer
309 .chunks(3)
310 .skip(channel)
311 .step_by(ch_cnt)
312 .map(|x| i32::from_le_bytes([x[0], x[1], x[2], 0]))
313 .collect()
314}
315
316pub fn load_wav_24bit<T>(path: T, sampling_rate: u32) -> Result<Vec<Vec<i32>>, &'static str>
328where
329 T: AsRef<std::path::Path>,
330{
331 let file = File::open(path);
332 if file.is_err() {
333 return Err(FILE_NOT_FOUND);
334 }
335 let mut file = file.unwrap();
336
337 check_riff_chunk(&mut file)?;
338 check_junk_chunk(&mut file)?;
339
340 let (channels, sr, bit_depth) = check_fmt_chunk(&mut file)?;
341 if sr != sampling_rate {
342 return Err(INVALID_SAMPLING_RATE);
343 }
344 let data = check_data_chunk(&mut file)?;
345
346 let channels = channels as usize;
347 let mut sampleses = Vec::with_capacity(channels);
348 match bit_depth {
349 8 => {
350 for i in 0..channels {
351 sampleses.push(to_vec_i32_from_i8(&data, i, channels));
352 }
353 Ok(sampleses)
354 }
355 16 => {
356 for i in 0..channels {
357 sampleses.push(to_vec_i32_from_i16(&data, i, channels));
358 }
359 Ok(sampleses)
360 }
361 24 => {
362 for i in 0..channels {
363 sampleses.push(to_vec_i32_from_i24(&data, i, channels));
364 }
365 Ok(sampleses)
366 }
367 _ => Err(INVALID_BIT_DEPTH),
368 }
369}
370
371fn to_vec_f32_from_i8(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<f32> {
372 if buffer.len() % ch_cnt != 0 {
373 panic!("Invalid buffer size");
374 }
375 buffer
376 .iter()
377 .skip(channel)
378 .step_by(ch_cnt)
379 .map(|&x| (x as f32 - 128.0) / 128.0)
380 .collect()
381}
382
383fn to_vec_f32_from_i16(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<f32> {
384 if buffer.len() % (ch_cnt * 2) != 0 {
385 panic!("Invalid buffer size");
386 }
387 buffer
388 .chunks(2)
389 .skip(channel)
390 .step_by(ch_cnt)
391 .map(|x| i16::from_le_bytes([x[0], x[1]]) as f32 / (1 << 15) as f32)
392 .collect()
393}
394
395fn to_vec_f32_from_i24(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<f32> {
396 if buffer.len() % (ch_cnt * 3) != 0 {
397 panic!("Invalid buffer size");
398 }
399 buffer
400 .chunks(3)
401 .skip(channel)
402 .step_by(ch_cnt)
403 .map(|x| i32::from_le_bytes([x[0], x[1], x[2], 0]) as f32 / (1 << 23) as f32)
404 .collect()
405}
406
407fn to_vec_f32_from_f32(buffer: &[u8], channel: usize, ch_cnt: usize) -> Vec<f32> {
408 if buffer.len() % (ch_cnt * 4) != 0 {
409 panic!("Invalid buffer size");
410 }
411 buffer
412 .chunks(4)
413 .skip(channel)
414 .step_by(ch_cnt)
415 .map(|x| f32::from_le_bytes([x[0], x[1], x[2], x[3]]))
416 .collect()
417}
418
419pub fn load_wav_32bit_float<T>(path: T, sampling_rate: u32) -> Result<Vec<Vec<f32>>, &'static str>
431where
432 T: AsRef<std::path::Path>,
433{
434 let file = File::open(path);
435 if file.is_err() {
436 return Err(FILE_NOT_FOUND);
437 }
438 let mut file = file.unwrap();
439
440 check_riff_chunk(&mut file)?;
441 check_junk_chunk(&mut file)?;
442
443 let (channels, sr, bit_depth) = check_fmt_chunk(&mut file)?;
444 if sr != sampling_rate {
445 return Err(INVALID_SAMPLING_RATE);
446 }
447 let data = check_data_chunk(&mut file)?;
448
449 let channels = channels as usize;
450 let mut sampleses = Vec::with_capacity(channels);
451 match bit_depth {
452 8 => {
453 for i in 0..channels {
454 sampleses.push(to_vec_f32_from_i8(&data, i, channels));
455 }
456 Ok(sampleses)
457 }
458 16 => {
459 for i in 0..channels {
460 sampleses.push(to_vec_f32_from_i16(&data, i, channels));
461 }
462 Ok(sampleses)
463 }
464 24 => {
465 for i in 0..channels {
466 sampleses.push(to_vec_f32_from_i24(&data, i, channels));
467 }
468 Ok(sampleses)
469 }
470 32 => {
471 for i in 0..channels {
472 sampleses.push(to_vec_f32_from_f32(&data, i, channels));
473 }
474 Ok(sampleses)
475 }
476 _ => Err(INVALID_BIT_DEPTH),
477 }
478}
479
480#[cfg(test)]
481mod tests {
482 use super::*;
483
484 #[test]
485 fn test_samples_i8_new_mono() {
486 let buffer = [0, 1, 2, 3, 4, 5, 6, 7];
487 let samples = to_vec_i8_from_i8(&buffer, 0, 1);
488 let mut expected = Vec::with_capacity(buffer.len());
489 for &x in buffer.iter() {
490 expected.push(x as i8 - 127 - 1);
491 }
492 assert_eq!(samples, expected);
493 }
494
495 #[test]
496 fn test_samples_i8_new_stereo() {
497 let buffer = [0, 1, 2, 3, 4, 5, 6, 7];
498 let samples = to_vec_i8_from_i8(&buffer, 0, 2);
499 let mut ch_0 = Vec::with_capacity(buffer.len() / 2);
500 let mut ch_1 = Vec::with_capacity(buffer.len() / 2);
501 for i in 0..buffer.len() / 2 {
502 ch_0.push(buffer[i * 2] as i8 - 127 - 1);
503 ch_1.push(buffer[i * 2 + 1] as i8 - 127 - 1);
504 }
505 assert_eq!(samples, ch_0);
506 let samples = to_vec_i8_from_i8(&buffer, 1, 2);
507 assert_eq!(samples, ch_1);
508 }
509
510 #[test]
511 fn test_samples_i16_new_mono() {
512 let buffer = [0, 0, 1, 0, 2, 0, 3, 0];
513 let samples = to_vec_i16_from_i16(&buffer, 0, 1);
514 let mut expected = Vec::with_capacity(buffer.len() / 2);
515 for i in 0..buffer.len() / 2 {
516 expected.push(i16::from_le_bytes([buffer[i * 2], buffer[i * 2 + 1]]));
517 }
518 assert_eq!(samples, expected);
519 }
520
521 #[test]
522 fn test_samples_i16_new_stereo() {
523 let buffer = [0, 0, 1, 0, 2, 0, 3, 0];
524 let samples = to_vec_i16_from_i16(&buffer, 0, 2);
525 let mut ch_0 = Vec::with_capacity(buffer.len() / 4);
526 let mut ch_1 = Vec::with_capacity(buffer.len() / 4);
527 for i in 0..buffer.len() / 4 {
528 ch_0.push(i16::from_le_bytes([buffer[i * 4], buffer[i * 4 + 1]]));
529 ch_1.push(i16::from_le_bytes([buffer[i * 4 + 2], buffer[i * 4 + 3]]));
530 }
531 assert_eq!(samples, ch_0);
532 let samples = to_vec_i16_from_i16(&buffer, 1, 2);
533 assert_eq!(samples, ch_1);
534 }
535
536 #[test]
537 fn test_samples_i16_from_i8() {
538 let buffer = [0, 1, 2, 3, 4, 5, 6, 7];
539 let samples = to_vec_i16_from_i8(&buffer, 0, 1);
540 let mut expected = Vec::with_capacity(buffer.len());
541 for &x in buffer.iter() {
542 expected.push(i16::from(x as i8 - 127 - 1) << 8);
543 }
544 assert_eq!(samples, expected);
545 }
546
547 #[test]
548 fn test_samples_i24_new_mono() {
549 let buffer = [0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0];
550 let samples = to_vec_i32_from_i24(&buffer, 0, 1);
551 let mut expected = Vec::with_capacity(buffer.len() / 3);
552 for i in 0..buffer.len() / 3 {
553 expected.push(i32::from_le_bytes([
554 buffer[i * 3],
555 buffer[i * 3 + 1],
556 buffer[i * 3 + 2],
557 0,
558 ]));
559 }
560 assert_eq!(samples, expected);
561 }
562
563 #[test]
564 fn test_samples_i24_new_stereo() {
565 let buffer = [0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0];
566 let samples = to_vec_i32_from_i24(&buffer, 0, 2);
567 let mut ch_0 = Vec::with_capacity(buffer.len() / 6);
568 let mut ch_1 = Vec::with_capacity(buffer.len() / 6);
569 for i in 0..buffer.len() / 6 {
570 ch_0.push(i32::from_le_bytes([
571 buffer[i * 6],
572 buffer[i * 6 + 1],
573 buffer[i * 6 + 2],
574 0,
575 ]));
576 ch_1.push(i32::from_le_bytes([
577 buffer[i * 6 + 3],
578 buffer[i * 6 + 4],
579 buffer[i * 6 + 5],
580 0,
581 ]));
582 }
583 assert_eq!(samples, ch_0);
584 let samples = to_vec_i32_from_i24(&buffer, 1, 2);
585 assert_eq!(samples, ch_1);
586 }
587
588 #[test]
589 fn test_samples_i24_from_i8() {
590 let buffer = [0, 1, 2, 3, 4, 5, 6, 7];
591 let samples = to_vec_i32_from_i8(&buffer, 0, 1);
592 let mut expected = Vec::with_capacity(buffer.len());
593 for &x in buffer.iter() {
594 expected.push(i32::from(x as i8 - 127 - 1) << 16);
595 }
596 assert_eq!(samples, expected);
597 }
598
599 #[test]
600 fn test_samples_i24_from_i16() {
601 let buffer = [0, 0, 1, 0, 2, 0, 3, 0];
602 let samples = to_vec_i32_from_i16(&buffer, 0, 1);
603 let mut expected = Vec::with_capacity(buffer.len());
604 for i in 0..buffer.len() / 2 {
605 expected.push(i32::from_le_bytes([buffer[i * 2], buffer[i * 2 + 1], 0, 0]));
606 }
607 assert_eq!(samples, expected);
608 }
609
610 #[test]
611 fn test_samples_f32_new_mono() {
612 let buffer = [0, 0, 0, 0, 0, 0, 128, 63];
613 let samples = to_vec_f32_from_f32(&buffer, 0, 1);
614 let mut expected = Vec::with_capacity(buffer.len() / 4);
615 for i in 0..buffer.len() / 4 {
616 expected.push(f32::from_le_bytes([
617 buffer[i * 4],
618 buffer[i * 4 + 1],
619 buffer[i * 4 + 2],
620 buffer[i * 4 + 3],
621 ]));
622 }
623 assert_eq!(samples, expected);
624 }
625
626 #[test]
627 fn test_samples_f32_new_stereo() {
628 let buffer = [0, 0, 0, 0, 0, 0, 128, 63];
629 let samples = to_vec_f32_from_f32(&buffer, 0, 2);
630 let mut ch_0 = Vec::with_capacity(buffer.len() / 8);
631 let mut ch_1 = Vec::with_capacity(buffer.len() / 8);
632 for i in 0..buffer.len() / 8 {
633 ch_0.push(f32::from_le_bytes([
634 buffer[i * 8],
635 buffer[i * 8 + 1],
636 buffer[i * 8 + 2],
637 buffer[i * 8 + 3],
638 ]));
639 ch_1.push(f32::from_le_bytes([
640 buffer[i * 8 + 4],
641 buffer[i * 8 + 5],
642 buffer[i * 8 + 6],
643 buffer[i * 8 + 7],
644 ]));
645 }
646 assert_eq!(samples, ch_0);
647 let samples = to_vec_f32_from_f32(&buffer, 1, 2);
648 assert_eq!(samples, ch_1);
649 }
650
651 #[test]
652 fn test_samples_f32_from_i8() {
653 let buffer = [0, 1, 2, 3, 4, 5, 6, 7];
654 let samples = to_vec_f32_from_i8(&buffer, 0, 1);
655 let mut expected = Vec::with_capacity(buffer.len());
656 for &x in buffer.iter() {
657 expected.push((x as f32 - 128.0) / 128.0);
658 }
659 assert!(samples
660 .iter()
661 .zip(expected.iter())
662 .all(|(a, b)| (a - b).abs() < 0.0001));
663 }
664
665 #[test]
666 fn test_samples_f32_from_i16() {
667 let buffer = [0, 0, 1, 0, 2, 0, 3, 0];
668 let samples = to_vec_f32_from_i16(&buffer, 0, 1);
669 let mut expected = Vec::with_capacity(buffer.len() / 2);
670 for i in 0..buffer.len() / 2 {
671 expected
672 .push((i16::from_le_bytes([buffer[i * 2], buffer[i * 2 + 1]]) as f32) / 32767.0);
673 }
674 assert!(samples
675 .iter()
676 .zip(expected.iter())
677 .all(|(a, b)| (a - b).abs() < 0.0001));
678 }
679
680 #[test]
681 fn test_samples_f32_from_i24() {
682 let buffer = [0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0];
683 let samples = to_vec_f32_from_i24(&buffer, 0, 1);
684 let mut expected = Vec::with_capacity(buffer.len() / 3);
685 for i in 0..buffer.len() / 3 {
686 expected.push(
687 (i32::from_le_bytes([buffer[i * 3], buffer[i * 3 + 1], buffer[i * 3 + 2], 0])
688 as f32)
689 / 8388607.0,
690 );
691 }
692 assert!(samples
693 .iter()
694 .zip(expected.iter())
695 .all(|(a, b)| (a - b).abs() < 0.0001));
696 }
697
698 #[test]
699 fn test_samples_f32_from_f32() {
700 let buffer = [0, 0, 0, 0, 0, 0, 128, 63];
701 let samples = to_vec_f32_from_f32(&buffer, 0, 1);
702 let mut expected = Vec::with_capacity(buffer.len() / 4);
703 for i in 0..buffer.len() / 4 {
704 expected.push(f32::from_le_bytes([
705 buffer[i * 4],
706 buffer[i * 4 + 1],
707 buffer[i * 4 + 2],
708 buffer[i * 4 + 3],
709 ]));
710 }
711 assert_eq!(samples, expected);
712 }
713}