pub struct WavWriter<'a> {
io: Box<ByteWriter<'a>>,
data_pos: u64,
+ be: bool,
+ bits: u8,
}
fn write_byte(wr: &mut ByteWriter, sample: u8) -> ByteIOResult<()> {
impl<'a> WavWriter<'a> {
pub fn new(name: &str) -> Self {
let file = File::create(name).unwrap();
+ let file = std::io::BufWriter::new(file);
let fw = Box::new(FileWriter::new_write(file));
let io = ByteWriter::new(Box::leak(fw));
- WavWriter { io: Box::new(io), data_pos: 0 }
+ WavWriter { io: Box::new(io), data_pos: 0, be: false, bits: 0 }
}
pub fn write_header(&mut self, ainfo: NAAudioInfo) -> ByteIOResult<()> {
let bits = ainfo.get_format().get_bits() as usize;
self.io.write_u16le(ainfo.get_channels() as u16)?;
self.io.write_u32le(ainfo.get_sample_rate() as u32)?;
- if bits < 16 {
+ if bits <= 8 {
self.io.write_u32le((ainfo.get_channels() as u32) * (ainfo.get_sample_rate() as u32))?;
self.io.write_u16le(ainfo.get_channels() as u16)?; // block align
self.io.write_u16le(8)?;
self.io.write_buf(b"data")?;
self.io.write_u32le(0)?;
+ self.bits = bits as u8;
+ self.be = ainfo.get_format().is_be();
self.data_pos = self.io.tell();
Ok(())
}
write_data!(&mut self.io, buf, write_f32);
}
NABufferType::AudioPacked(ref buf) => {
- self.io.write_buf(buf.get_data().as_slice())?;
+ let data = buf.get_data();
+ match self.bits {
+ _ if !self.be && (self.bits & 7) == 0 => {
+ self.io.write_buf(data.as_slice())?;
+ },
+ 8 => {
+ self.io.write_buf(data.as_slice())?;
+ },
+ 12 if !self.be => {
+ let mut src = data.chunks_exact(3);
+ while let Some(chunk) = src.next() {
+ self.io.write_byte(chunk[0] << 4)?;
+ self.io.write_byte((chunk[1] << 4) | (chunk[0] >> 4))?;
+ self.io.write_byte(chunk[1] & 0xF0)?;
+ self.io.write_byte(chunk[2])?;
+ }
+ let tail = src.remainder();
+ if tail.len() == 2 {
+ self.io.write_byte(tail[0] << 4)?;
+ self.io.write_byte(tail[1] << 4)?;
+ }
+ }
+ 16 => {
+ for samp in data.chunks(2) {
+ self.io.write_byte(samp[1])?;
+ self.io.write_byte(samp[0])?;
+ }
+ },
+ 24 => {
+ for samp in data.chunks(3) {
+ self.io.write_byte(samp[2])?;
+ self.io.write_byte(samp[1])?;
+ self.io.write_byte(samp[0])?;
+ }
+ },
+ 32 => {
+ for samp in data.chunks(4) {
+ self.io.write_byte(samp[3])?;
+ self.io.write_byte(samp[2])?;
+ self.io.write_byte(samp[1])?;
+ self.io.write_byte(samp[0])?;
+ }
+ },
+ _ => unimplemented!(),
+ };
}
_ => {},
};
let res = self.io.write_u32le((size - 8) as u32);
let res = self.io.seek(SeekFrom::Start(self.data_pos - 4));
let res = self.io.write_u32le(((size as u64) - self.data_pos) as u32);
+ let res = self.io.flush();
}
}
}