Parse a WAV file into SoundData.
(data: &[u8])
| 284 | |
| 285 | /// Parse a WAV file into SoundData. |
| 286 | pub fn parse_wav(data: &[u8]) -> Option<SoundData> { |
| 287 | if data.len() < 44 { return None; } |
| 288 | if &data[0..4] != b"RIFF" || &data[8..12] != b"WAVE" { return None; } |
| 289 | |
| 290 | let channels = u16::from_le_bytes([data[22], data[23]]); |
| 291 | let sample_rate = u32::from_le_bytes([data[24], data[25], data[26], data[27]]); |
| 292 | let bits_per_sample = u16::from_le_bytes([data[34], data[35]]); |
| 293 | |
| 294 | let mut offset = 36; |
| 295 | while offset + 8 < data.len() { |
| 296 | let chunk_id = &data[offset..offset + 4]; |
| 297 | let chunk_size = u32::from_le_bytes([ |
| 298 | data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7], |
| 299 | ]) as usize; |
| 300 | |
| 301 | if chunk_id == b"data" { |
| 302 | let pcm_data = &data[offset + 8..std::cmp::min(offset + 8 + chunk_size, data.len())]; |
| 303 | let samples = match bits_per_sample { |
| 304 | 16 => pcm_data.chunks_exact(2) |
| 305 | .map(|chunk| i16::from_le_bytes([chunk[0], chunk[1]]) as f32 / 32768.0) |
| 306 | .collect(), |
| 307 | 8 => pcm_data.iter() |
| 308 | .map(|&b| (b as f32 - 128.0) / 128.0) |
| 309 | .collect(), |
| 310 | _ => return None, |
| 311 | }; |
| 312 | return Some(SoundData { samples, sample_rate, channels }); |
| 313 | } |
| 314 | offset += 8 + chunk_size; |
| 315 | } |
| 316 | None |
| 317 | } |
| 318 | |
| 319 | /// Parse an MP3 file into SoundData. |
| 320 | #[cfg(feature = "mp3")] |
no test coverage detected