1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use string::{String, ToString};
use vec::Vec;
pub struct WAV {
pub channels: u16,
pub sample_rate: u32,
pub sample_bits: u16,
pub data: Vec<u8>,
}
impl WAV {
pub fn new() -> Self {
WAV {
channels: 0,
sample_rate: 0,
sample_bits: 0,
data: Vec::new(),
}
}
pub fn from_data(file_data: &[u8]) -> Self {
let mut ret = WAV::new();
let get = |i: usize| -> u8 {
match file_data.get(i) {
Some(byte) => *byte,
None => 0,
}
};
let getw = |i: usize| -> u16 { (get(i) as u16) + ((get(i + 1) as u16) << 8) };
let getd = |i: usize| -> u32 {
(get(i) as u32) + ((get(i + 1) as u32) << 8) + ((get(i + 2) as u32) << 16) +
((get(i + 3) as u32) << 24)
};
let gets = |start: usize, len: usize| -> String {
(start..start + len).map(|i| get(i) as char).collect::<String>()
};
let mut i = 0;
let root_type = gets(i, 4);
i += 4;
i += 4;
if root_type == "RIFF" {
let media_type = gets(i, 4);
i += 4;
if media_type == "WAVE" {
loop {
let chunk_type = gets(i, 4);
i += 4;
let chunk_size = getd(i);
i += 4;
if chunk_type.len() == 0 || chunk_size == 0 {
break;
}
if chunk_type == "fmt " {
ret.channels = getw(i + 2);
ret.sample_rate = getd(i + 4);
ret.sample_bits = getw(i + 0xE);
}
if chunk_type == "data" {
ret.data = file_data[i .. chunk_size as usize].to_vec();
}
i += chunk_size as usize;
}
}
}
ret
}
}