use std::{ fs, io::{Read, Seek}, }; #[allow(unused)] pub struct AudioSample { pub data: Vec>, pub format: FormatData, } #[derive(Debug)] #[allow(unused)] pub struct FormatData { pub audio_format: u16, pub nbr_channels: u16, pub frequency: u32, pub byte_per_second: u32, pub byte_per_block: u16, pub bits_per_sample: u16, } impl AudioSample { pub fn new(path: &str) -> Self { let mut file = fs::File::open(path).unwrap(); file.seek(std::io::SeekFrom::Current(12)).unwrap(); let format = Self::read_format_data(&mut file); let data = Self::read_data(&mut file, &format); Self { data, format } } pub fn mono_data(&self) -> Vec { self.data.iter().map(|channels| channels[0]).collect() } fn read_format_data(file: &mut fs::File) -> FormatData { file.seek(std::io::SeekFrom::Current(8)).unwrap(); let mut buf = [0u8; 16]; file.read_exact(&mut buf).unwrap(); FormatData { audio_format: u16::from_le_bytes([buf[0], buf[1]]), nbr_channels: u16::from_le_bytes([buf[2], buf[3]]), frequency: u32::from_le_bytes([buf[4], buf[5], buf[6], buf[7]]), byte_per_second: u32::from_le_bytes([buf[8], buf[9], buf[10], buf[11]]), byte_per_block: u16::from_le_bytes([buf[12], buf[13]]), bits_per_sample: u16::from_le_bytes([buf[14], buf[15]]), } } fn read_data(file: &mut fs::File, format: &FormatData) -> Vec> { file.seek(std::io::SeekFrom::Current(8)).unwrap(); let mut data = vec![]; loop { let mut sample = vec![0f32; format.nbr_channels as usize]; let mut buf = vec![0u8; format.byte_per_block as usize]; if file.read_exact(&mut buf).is_err() { break; }; for i in 0..(format.nbr_channels as usize) { match format.bits_per_sample { 16 => { let value = i16::from_le_bytes([buf[i * 2], buf[i * 2 + 1]]); sample[i as usize] = value as f32 / i16::MAX as f32; } _ => unimplemented!(), } } data.push(sample); } data } }