From 033d6b00ff1e99afb0304800fa1b20322933a5c5 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 5 Nov 2022 10:11:53 +0100 Subject: [PATCH] rework WAV writer a bit and add 12-bit PCM support --- src/wavwriter.rs | 76 +++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/src/wavwriter.rs b/src/wavwriter.rs index c0b324d..ab26f6c 100644 --- a/src/wavwriter.rs +++ b/src/wavwriter.rs @@ -79,7 +79,7 @@ impl<'a> WavWriter<'a> { 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)?; @@ -112,35 +112,51 @@ impl<'a> WavWriter<'a> { write_data!(&mut self.io, buf, write_f32); } NABufferType::AudioPacked(ref buf) => { - if !self.be || self.bits == 8 { - self.io.write_buf(buf.get_data().as_slice())?; - } else { - let data = buf.get_data(); - match self.bits { - 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 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!(), + }; } _ => {}, }; -- 2.30.2