041095733181831492ed6f663deb5e04f6c1cb3a
[nihav.git] / nihav-duck / src / codecs / dkadpcm.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use std::str::FromStr;
4
5 const IMA_MAX_STEP: u8 = 88;
6 struct IMAState {
7 predictor: i32,
8 step: usize,
9 }
10
11 impl IMAState {
12 fn new() -> Self {
13 Self {
14 predictor: 0,
15 step: 0,
16 }
17 }
18 fn reset(&mut self, predictor: i16, step: u8) {
19 self.predictor = predictor as i32;
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;
25 let diff = (((2 * (nibble & 7) + 1) as i32) * IMA_STEP_TABLE[self.step]) >> 3;
26 let sample = if !sign { self.predictor + diff } else { self.predictor - diff };
27 self.predictor = sample.max(std::i16::MIN as i32).min(std::i16::MAX as i32);
28 self.step = istep.max(0).min(IMA_MAX_STEP as isize) as usize;
29 self.predictor as i16
30 }
31 }
32
33 struct DuckADPCMDecoder {
34 ainfo: NAAudioInfo,
35 chmap: NAChannelMap,
36 is_dk3: bool,
37 ch_state: [IMAState; 2],
38 block_len: usize,
39 }
40
41 impl 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
53 impl NADecoder for DuckADPCMDecoder {
54 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
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 }
72 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
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;
80 let abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
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);
84 let dst = adata.get_data_mut().unwrap();
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;
103 let mut diff_val: i32 = diffpred as i32;
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 }
121 let sum0 = self.ch_state[0].expand_sample(nib0) as i32;
122 let diff = self.ch_state[1].expand_sample(nib1) as i32;
123 let sum1 = self.ch_state[0].expand_sample(nib2) as i32;
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);
161 Ok(Rc::new(RefCell::new(frm)))
162 } else {
163 Err(DecoderError::InvalidData)
164 }
165 }
166 }
167
168 pub fn get_decoder_dk3() -> Box<NADecoder> {
169 Box::new(DuckADPCMDecoder::new(true))
170 }
171
172 pub fn get_decoder_dk4() -> Box<NADecoder> {
173 Box::new(DuckADPCMDecoder::new(false))
174 }
175
176 #[cfg(test)]
177 mod test {
178 use nihav_core::codecs::RegisteredDecoders;
179 use nihav_core::demuxers::RegisteredDemuxers;
180 use nihav_core::test::dec_video::*;
181 use crate::codecs::duck_register_all_codecs;
182 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
183 #[test]
184 fn test_dk3() {
185 let mut dmx_reg = RegisteredDemuxers::new();
186 generic_register_all_demuxers(&mut dmx_reg);
187 let mut dec_reg = RegisteredDecoders::new();
188 duck_register_all_codecs(&mut dec_reg);
189
190 let file = "assets/Duck/AVI-DUCK-dk3.duk";
191 test_decode_audio("avi", file, Some(100), "dk3", &dmx_reg, &dec_reg);
192 }
193 #[test]
194 fn test_dk4() {
195 let mut dmx_reg = RegisteredDemuxers::new();
196 generic_register_all_demuxers(&mut dmx_reg);
197 let mut dec_reg = RegisteredDecoders::new();
198 duck_register_all_codecs(&mut dec_reg);
199
200 let file = "assets/Duck/virtuafighter2-opening1.avi";
201 test_decode_audio("avi", file, Some(100), "dk4", &dmx_reg, &dec_reg);
202 }
203 }
204
205 const IMA_STEPS: [i8; 16] = [
206 -1, -1, -1, -1, 2, 4, 6, 8,
207 -1, -1, -1, -1, 2, 4, 6, 8
208 ];
209
210 const IMA_STEP_TABLE: [i32; 89] = [
211 7, 8, 9, 10, 11, 12, 13, 14,
212 16, 17, 19, 21, 23, 25, 28, 31,
213 34, 37, 41, 45, 50, 55, 60, 66,
214 73, 80, 88, 97, 107, 118, 130, 143,
215 157, 173, 190, 209, 230, 253, 279, 307,
216 337, 371, 408, 449, 494, 544, 598, 658,
217 724, 796, 876, 963, 1060, 1166, 1282, 1411,
218 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
219 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
220 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
221 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
222 ];