use crate::FileLoader;
#[derive(Debug)]
pub struct WavFile {
data: Vec< f32 >,
}
impl WavFile {
pub fn new() -> Self {
Self {
data: Vec::new(),
}
}
pub fn data( &self ) -> &Vec<f32> {
&self.data
}
pub fn load( &mut self, fileloader: &mut dyn FileLoader, filename: &str ) -> bool {
let mut f = fileloader.open( &filename );
if ! f.is_valid() {
println!("Couldn't open file: {}", filename);
return false;
}
for b in &[ b'R', b'I', b'F', b'F' ] {
let b1 = f.read_u8();
if *b != b1 {
println!("Wrong RIFF signature {:#02x} != {:#02x}", b, b1 );
return false;
}
}
let size = f.read_u32();
dbg!(size);
for b in &[ b'W', b'A', b'V', b'E' ] {
let b1 = f.read_u8();
if *b != b1 {
println!("Wrong WAVE signature {:#02x} != {:#02x}", b, b1 );
return false;
}
}
for b in &[ b'f', b'm', b't', b' ' ] {
let b1 = f.read_u8();
if *b != b1 {
println!("Wrong fmt signature {:#02x} != {:#02x}", b, b1 );
return false;
}
}
let fmt_len = f.read_u32();
dbg!(fmt_len);
if fmt_len != 16 {
println!("Unexpected fmt length {}", fmt_len );
return false;
}
let fmt_type = f.read_u16();
dbg!(fmt_type);
if fmt_len != 16 {
println!("Unexpected fmt type {} (not 1/PCM", fmt_type );
return false;
}
let channels = f.read_u16();
dbg!(channels);
let sample_rate = f.read_u32();
let byte_rate = f.read_u32();
let block_size = f.read_u16();
let bits_per_sample = f.read_u16();
dbg!(sample_rate);
dbg!(byte_rate);
dbg!(block_size);
dbg!(bits_per_sample);
while !f.eof() {
let mut chunk_type = [0u8;4];
for b in &mut chunk_type {
*b = f.read_u8();
}
let chunk_size = f.read_u32();
let chunk_type = std::str::from_utf8( &chunk_type ).unwrap_or( "" );
dbg!( chunk_type );
match chunk_type {
"data" => {
println!("data chunk");
let blocks = chunk_size / block_size as u32;
match bits_per_sample {
16 => {
for _ in 0..blocks {
let w = f.read_u16();
let w = unsafe {
std::mem::transmute::< u16, i16 >( w )
};
let f = 2.0*( w as f32 )/( 0xffff as f32 ) - 0.0;
self.data.push( f );
if channels == 1 { self.data.push( f );
}
};
println!("");
},
8 => {
for _ in 0..blocks {
let w = f.read_u8();
let f = 2.0*( w as f32 )/( 0xff as f32 ) - 1.0;
self.data.push( f );
if channels == 1 { self.data.push( f );
}
};
println!("");
},
bps => {
println!("Unhandled bits per sample {}", bps );
return false;
}
}
},
"" => {
println!("None chunk ''");
break;
},
_ => {
println!("Unhandled chunk type: {:?} size: skipping {}", chunk_type, chunk_size);
for _ in 0..chunk_size {
f.read_u8();
};
},
};
}
false
}
}