make Wave writer output big-endian audio correctly
[nihav-tool.git] / src / wavwriter.rs
index 51700f7b7502badfd852c7216f35fec9cba3b79c..a22887650f8e1ca01f254e523bffc0e504e2befc 100644 (file)
@@ -8,6 +8,8 @@ use std::io::SeekFrom;
 pub struct WavWriter<'a> {
     io: Box<ByteWriter<'a>>,
     data_pos: u64,
+    be: bool,
+    bits: u8,
 }
 
 fn write_byte(wr: &mut ByteWriter, sample: u8) -> ByteIOResult<()> {
@@ -37,11 +39,19 @@ macro_rules! write_data {
         let nch = ainfo.get_channels() as usize;
         let mut offs: Vec<usize> = Vec::with_capacity(nch);
         for ch in 0..nch { offs.push($buf.get_offset(ch)); }
+        let is_planar = $buf.get_step() == 1;
         let data = $buf.get_data();
 
-        for i in 0..len {
-            for ch in 0..nch {
-                let sample = data[offs[ch] + i];
+        if is_planar {
+            for i in 0..len {
+                for ch in 0..nch {
+                    let sample = data[offs[ch] + i];
+                    $write($wr, sample)?;
+                }
+            }
+        } else {
+            for i in 0..len*nch {
+                let sample = data[i];
                 $write($wr, sample)?;
             }
         }
@@ -49,11 +59,11 @@ macro_rules! write_data {
 }
 
 impl<'a> WavWriter<'a> {
-    pub fn new(name: &String) -> Self {
+    pub fn new(name: &str) -> Self {
         let file = File::create(name).unwrap();
         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;
@@ -81,6 +91,8 @@ impl<'a> WavWriter<'a> {
         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(())
     }
@@ -99,7 +111,35 @@ impl<'a> WavWriter<'a> {
                 write_data!(&mut self.io, buf, write_f32);
             }
             NABufferType::AudioPacked(ref buf) => {
-                self.io.write_buf(buf.get_data().as_slice())?;
+                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!(),
+                    };
+                }
             }
             _ => {},
         };