duck: switch some codecs to new testing system
[nihav.git] / nihav-duck / src / codecs / dkadpcm.rs
CommitLineData
029d2552
KS
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use std::str::FromStr;
4
5const IMA_MAX_STEP: u8 = 88;
6struct IMAState {
7 predictor: i32,
8 step: usize,
9}
10
11impl IMAState {
12 fn new() -> Self {
13 Self {
14 predictor: 0,
15 step: 0,
16 }
17 }
18 fn reset(&mut self, predictor: i16, step: u8) {
8a7352c0 19 self.predictor = i32::from(predictor);
029d2552
KS
20 self.step = step.min(IMA_MAX_STEP) as usize;
21 }
22 fn expand_sample(&mut self, nibble: u8) -> i16 {
23 let istep = (self.step as isize) + (IMA_STEPS[nibble as usize] as isize);
24 let sign = (nibble & 8) != 0;
8a7352c0 25 let diff = (i32::from(2 * (nibble & 7) + 1) * IMA_STEP_TABLE[self.step]) >> 3;
029d2552 26 let sample = if !sign { self.predictor + diff } else { self.predictor - diff };
8a7352c0 27 self.predictor = sample.max(i32::from(std::i16::MIN)).min(i32::from(std::i16::MAX));
029d2552
KS
28 self.step = istep.max(0).min(IMA_MAX_STEP as isize) as usize;
29 self.predictor as i16
30 }
31}
32
33struct DuckADPCMDecoder {
34 ainfo: NAAudioInfo,
35 chmap: NAChannelMap,
36 is_dk3: bool,
37 ch_state: [IMAState; 2],
38 block_len: usize,
39}
40
41impl DuckADPCMDecoder {
42 fn new(is_dk3: bool) -> Self {
43 Self {
44 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
45 chmap: NAChannelMap::new(),
46 is_dk3,
47 ch_state: [IMAState::new(), IMAState::new()],
48 block_len: 0,
49 }
50 }
51}
52
53impl NADecoder for DuckADPCMDecoder {
01613464 54 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
029d2552
KS
55 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
56 validate!(ainfo.get_block_len() > 16);
57 self.block_len = ainfo.get_block_len();
58 let channels = ainfo.get_channels();
59 validate!(channels == 2 || (!self.is_dk3 && channels == 1));
60 let len = if self.is_dk3 {
61 ((self.block_len - 16) * 2 / 3) * 2
62 } else {
63 (self.block_len - 4 * (channels as usize)) * 2 / (channels as usize)
64 };
65 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), channels, SND_S16P_FORMAT, len);
66 self.chmap = NAChannelMap::from_str(if channels == 1 { "C" } else { "L,R" }).unwrap();
67 Ok(())
68 } else {
69 Err(DecoderError::InvalidData)
70 }
71 }
01613464 72 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
029d2552
KS
73 let info = pkt.get_stream().get_info();
74 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
75 let pktbuf = pkt.get_buffer();
76 validate!(pktbuf.len() > (if self.is_dk3 { 16 } else { 4 * self.chmap.num_channels() }));
77 let nblocks = pktbuf.len() / self.block_len;
78 let out_block_len = self.ainfo.get_block_len();
79 let duration = out_block_len * nblocks;
b70cc006 80 let abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
029d2552
KS
81 let mut adata = abuf.get_abuf_i16().unwrap();
82 let mut off0 = adata.get_offset(0);
83 let mut off1 = adata.get_offset(1);
1a967e6b 84 let dst = adata.get_data_mut().unwrap();
029d2552
KS
85
86 for blk in pktbuf.chunks_exact(self.block_len) {
87 let mut mr = MemoryReader::new_read(blk);
88 let mut br = ByteReader::new(&mut mr);
89 if self.is_dk3 {
90 let _typeid = br.read_byte()?;
91 let _version = br.read_byte()?;
92 let _srate = br.read_u32le()?;
93 let samples = br.read_u32le()? as usize;
94 let sumpred = br.read_u16le()? as i16;
95 let diffpred = br.read_u16le()? as i16;
96 let sumstep = br.read_byte()?;
97 let diffstep = br.read_byte()?;
98 validate!(sumstep <= IMA_MAX_STEP && diffstep <= IMA_MAX_STEP);
99 validate!(samples <= out_block_len);
100 self.ch_state[0].reset(sumpred, sumstep);
101 self.ch_state[1].reset(diffpred, diffstep);
102 let mut last_nib = 0;
8a7352c0 103 let mut diff_val: i32 = i32::from(diffpred);
029d2552
KS
104 for x in (0..out_block_len).step_by(2) {
105 let nib0;
106 let nib1;
107 let nib2;
108 if (x & 2) == 0 {
109 let b0 = br.read_byte()?;
110 let b1 = br.read_byte()?;
111 nib0 = b0 & 0xF;
112 nib1 = b0 >> 4;
113 nib2 = b1 & 0xF;
114 last_nib = b1 >> 4;
115 } else {
116 let b0 = br.read_byte()?;
117 nib0 = last_nib;
118 nib1 = b0 & 0xF;
119 nib2 = b0 >> 4;
120 }
8a7352c0
KS
121 let sum0 = i32::from(self.ch_state[0].expand_sample(nib0));
122 let diff = i32::from(self.ch_state[1].expand_sample(nib1));
123 let sum1 = i32::from(self.ch_state[0].expand_sample(nib2));
029d2552
KS
124 diff_val = (diff_val + diff) >> 1;
125 dst[off0 + x + 0] = (sum0 + diff_val) as i16;
126 dst[off1 + x + 0] = (sum0 - diff_val) as i16;
127 diff_val = (diff_val + diff) >> 1;
128 dst[off0 + x + 1] = (sum1 + diff_val) as i16;
129 dst[off1 + x + 1] = (sum1 - diff_val) as i16;
130 diff_val = diff;
131 }
132 } else {
133 let nchannels = self.chmap.num_channels();
134 for ch in 0..nchannels {
135 let pred = br.read_u16le()? as i16;
136 let step = br.read_byte()?;
137 br.read_skip(1)?;
138 validate!(step <= IMA_MAX_STEP);
139 self.ch_state[ch].reset(pred, step);
140 }
141 if nchannels == 2 {
142 for x in 0..out_block_len {
143 let b = br.read_byte()?;
144 dst[off0 + x] = self.ch_state[0].expand_sample(b >> 4);
145 dst[off1 + x] = self.ch_state[1].expand_sample(b & 0xF);
146 }
147 } else {
148 for x in (0..out_block_len).step_by(2) {
149 let b = br.read_byte()?;
150 dst[off0 + x + 0] = self.ch_state[0].expand_sample(b >> 4);
151 dst[off0 + x + 1] = self.ch_state[0].expand_sample(b & 0xF);
152 }
153 }
154 }
155 off0 += out_block_len;
156 off1 += out_block_len;
157 }
158 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
159 frm.set_duration(Some(duration as u64));
160 frm.set_keyframe(false);
171860fc 161 Ok(frm.into_ref())
029d2552
KS
162 } else {
163 Err(DecoderError::InvalidData)
164 }
165 }
f9be4e75
KS
166 fn flush(&mut self) {
167 }
029d2552
KS
168}
169
6011e201 170pub fn get_decoder_dk3() -> Box<dyn NADecoder> {
029d2552
KS
171 Box::new(DuckADPCMDecoder::new(true))
172}
173
6011e201 174pub fn get_decoder_dk4() -> Box<dyn NADecoder> {
029d2552
KS
175 Box::new(DuckADPCMDecoder::new(false))
176}
177
178#[cfg(test)]
179mod test {
180 use nihav_core::codecs::RegisteredDecoders;
181 use nihav_core::demuxers::RegisteredDemuxers;
182 use nihav_core::test::dec_video::*;
183 use crate::codecs::duck_register_all_codecs;
184 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
185 #[test]
186 fn test_dk3() {
187 let mut dmx_reg = RegisteredDemuxers::new();
188 generic_register_all_demuxers(&mut dmx_reg);
189 let mut dec_reg = RegisteredDecoders::new();
190 duck_register_all_codecs(&mut dec_reg);
191
16b13997
KS
192 //let file = "assets/Duck/AVI-DUCK-dk3.duk";
193 //test_decode_audio("avi", file, Some(100), None/*Some("dk3")*/, &dmx_reg, &dec_reg);
194 test_decoding("avi", "adpcm-dk3", "assets/Duck/AVI-DUCK-dk3.duk", None, &dmx_reg, &dec_reg,
195 ExpectedTestResult::MD5([0xa48fae0a, 0xa536b27f, 0x169ecc19, 0x8436fade]));
029d2552
KS
196 }
197 #[test]
198 fn test_dk4() {
199 let mut dmx_reg = RegisteredDemuxers::new();
200 generic_register_all_demuxers(&mut dmx_reg);
201 let mut dec_reg = RegisteredDecoders::new();
202 duck_register_all_codecs(&mut dec_reg);
203
16b13997
KS
204// let file = "assets/Duck/virtuafighter2-opening1.avi";
205// test_decode_audio("avi", file, Some(100), None/*Some("dk4")*/, &dmx_reg, &dec_reg);
206 test_decoding("avi", "adpcm-dk4", "assets/Duck/virtuafighter2-opening1.avi", None, &dmx_reg, &dec_reg,
207 ExpectedTestResult::MD5([0x04e40d15, 0xf65b3427, 0x1dd5181f, 0xf321b56f]));
029d2552
KS
208 }
209}
210
211const IMA_STEPS: [i8; 16] = [
212 -1, -1, -1, -1, 2, 4, 6, 8,
213 -1, -1, -1, -1, 2, 4, 6, 8
214];
215
216const IMA_STEP_TABLE: [i32; 89] = [
217 7, 8, 9, 10, 11, 12, 13, 14,
218 16, 17, 19, 21, 23, 25, 28, 31,
219 34, 37, 41, 45, 50, 55, 60, 66,
220 73, 80, 88, 97, 107, 118, 130, 143,
221 157, 173, 190, 209, 230, 253, 279, 307,
222 337, 371, 408, 449, 494, 544, 598, 658,
223 724, 796, 876, 963, 1060, 1166, 1282, 1411,
224 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
225 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
226 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
227 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
228];