aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2020-04-17 09:12:17 +0200
committerKostya Shishkov <kostya.shishkov@gmail.com>2020-04-17 09:12:17 +0200
commit3e91c67bfde3462596707d2d82fa6271f8b99301 (patch)
treeb521e4cbaedd4a7b040ddefa90020f73d37f1994
parent02c01d44e486b34dee5948f6d5821ea844014d70 (diff)
downloadnihav-3e91c67bfde3462596707d2d82fa6271f8b99301.tar.gz
vmd: handle IMA ADPCM chunks with odd number of samples correctly
-rw-r--r--nihav-game/src/codecs/vmd.rs17
1 files changed, 10 insertions, 7 deletions
diff --git a/nihav-game/src/codecs/vmd.rs b/nihav-game/src/codecs/vmd.rs
index 904fe1f..c8ef7da 100644
--- a/nihav-game/src/codecs/vmd.rs
+++ b/nihav-game/src/codecs/vmd.rs
@@ -471,7 +471,7 @@ impl NADecoder for VMDAudioDecoder {
self.blk_size = (ainfo.get_block_len() + 1) * channels;
self.mode = VMDAudioMode::DPCM;
} else {
- self.blk_size = ainfo.get_block_len() / 2 + 3;
+ self.blk_size = (ainfo.get_block_len() + 1) / 2 + 3;
self.mode = VMDAudioMode::ADPCM;
}
};
@@ -603,7 +603,7 @@ impl NADecoder for VMDAudioDecoder {
let mut ima = IMAState::new();
for _ in 0..nblocks {
if (mask & 1) != 0 {
- doff += (self.blk_size - 3) * 2;
+ doff += self.blk_align;
mask >>= 1;
continue;
}
@@ -611,11 +611,14 @@ impl NADecoder for VMDAudioDecoder {
let step = br.read_byte()?;
validate!((step as usize) < IMA_STEP_TABLE.len());
ima.reset(pred, step);
- for _ in 3..self.blk_size {
- let b = br.read_byte()?;
- dst[doff] = ima.expand_sample(b >> 4);
- doff += 1;
- dst[doff] = ima.expand_sample(b & 0xF);
+ let mut b = 0;
+ for i in 0..self.blk_align {
+ if (i & 1) == 0 {
+ b = br.read_byte()?;
+ dst[doff] = ima.expand_sample(b >> 4);
+ } else {
+ dst[doff] = ima.expand_sample(b & 0xF);
+ }
doff += 1;
}
mask >>= 1;