]> git.nihav.org Git - nihav.git/blobdiff - nihav-codec-support/src/codecs/imaadpcm.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-codec-support / src / codecs / imaadpcm.rs
index a2da1d316bc90dd42abddce01d26941b4d3a00ff..dcd1ed44497810eaf6b07769ca3f4c9e5be3275a 100644 (file)
@@ -24,6 +24,7 @@ pub const IMA_STEP_TABLE: [i32; 89] = [
 ///! Maximum step value for IMA ADPCM.
 pub const IMA_MAX_STEP: u8 = 88;
 
+#[derive(Clone,Copy,Debug)]
 ///! Decoder for IMA ADPCM.
 pub struct IMAState {
     ///! Current sample value.
@@ -51,10 +52,17 @@ impl IMAState {
         let sign = (nibble & 8) != 0;
         let diff = (i32::from(2 * (nibble & 7) + 1) * IMA_STEP_TABLE[self.step]) >> 3;
         let sample = if !sign { self.predictor + diff } else { self.predictor - diff };
-        self.predictor = sample.max(i32::from(std::i16::MIN)).min(i32::from(std::i16::MAX));
+        self.predictor = sample.max(i32::from(i16::MIN)).min(i32::from(i16::MAX));
         self.step = istep.max(0).min(IMA_MAX_STEP as isize) as usize;
         self.predictor as i16
     }
+    ///! Computes an encoded nibble from an input sample.
+    pub fn compress_sample(&self, sample: i16) -> u8 {
+        let diff = i32::from(sample) - self.predictor;
+        let sign = if diff >= 0 { 0 } else { 8 };
+        let nib = (diff.abs() * 4 / IMA_STEP_TABLE[self.step]).min(7) as u8;
+        nib | sign
+    }
 }
 
 impl Default for IMAState {