1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
5 const ADAPT_TABLE: [i32; 16] = [
6 230, 230, 230, 230, 307, 409, 512, 614,
7 768, 614, 512, 409, 307, 230, 230, 230
9 const ADAPT_COEFFS: [[i32; 2]; 7] = [
10 [ 256, 0 ], [ 512, -256 ], [ 0, 0 ], [ 192, 64 ],
11 [ 240, 0 ], [ 460, -208 ], [ 392, -232 ]
24 fn expand_nibble(&mut self, nibble: u8) -> i16 {
25 let mul = if (nibble & 8) == 0 { i32::from(nibble) } else { i32::from(nibble) - 16 };
26 let pred = ((self.sample1.wrapping_mul(self.coef1) + self.sample2.wrapping_mul(self.coef2)) >> 8) + self.delta.wrapping_mul(mul);
27 self.sample2 = self.sample1;
28 self.sample1 = pred.max(-0x8000).min(0x7FFF);
29 self.delta = (ADAPT_TABLE[nibble as usize].wrapping_mul(self.delta) >> 8).max(16);
34 struct MSADPCMDecoder {
37 adapt_coeffs: Vec<[i32; 2]>,
45 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
46 chmap: NAChannelMap::new(),
47 adapt_coeffs: Vec::with_capacity(7),
54 impl NADecoder for MSADPCMDecoder {
55 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
56 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
57 self.block_len = ainfo.get_block_len();
58 let channels = ainfo.get_channels() as usize;
59 validate!(channels == 2 || channels == 1);
60 validate!(self.block_len >= 7 * channels + 1);
61 self.block_samps = (self.block_len / channels - 7) * 2 + 2;
62 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), channels as u8, SND_S16P_FORMAT, self.block_samps);
63 self.chmap = NAChannelMap::from_str(if channels == 1 { "C" } else { "L,R" }).unwrap();
64 self.adapt_coeffs.truncate(0);
65 if let Some(ref buf) = info.get_extradata() {
66 validate!(buf.len() >= 6);
67 validate!((buf.len() & 3) == 0);
68 let mut mr = MemoryReader::new_read(buf.as_slice());
69 let mut br = ByteReader::new(&mut mr);
70 let _smth = br.read_u16le()?;
71 let ncoeffs = br.read_u16le()? as usize;
72 validate!(buf.len() == ncoeffs * 4 + 4);
76 i32::from(br.read_u16le()? as i16),
77 i32::from(br.read_u16le()? as i16)];
78 self.adapt_coeffs.push(pair);
81 self.adapt_coeffs.extend_from_slice(&ADAPT_COEFFS);
85 Err(DecoderError::InvalidData)
88 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
89 let info = pkt.get_stream().get_info();
90 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
91 let pktbuf = pkt.get_buffer();
92 let channels = self.chmap.num_channels();
93 validate!(pktbuf.len() > 0 && (pktbuf.len() % self.block_len) == 0);
94 let nblocks = pktbuf.len() / self.block_len;
95 let nsamples = nblocks * self.block_samps;
96 let abuf = alloc_audio_buffer(self.ainfo, nsamples, self.chmap.clone())?;
97 let mut adata = abuf.get_abuf_i16().unwrap();
98 let mut off = [adata.get_offset(0), adata.get_offset(1)];
99 let dst = adata.get_data_mut().unwrap();
101 let mut pred = [Predictor::default(), Predictor::default()];
103 for blk in pktbuf.chunks(self.block_len) {
104 let mut mr = MemoryReader::new_read(blk);
105 let mut br = ByteReader::new(&mut mr);
106 for ch in 0..channels {
107 let coef_idx = br.read_byte()? as usize;
108 validate!(coef_idx < self.adapt_coeffs.len());
109 pred[ch].coef1 = self.adapt_coeffs[coef_idx][0];
110 pred[ch].coef2 = self.adapt_coeffs[coef_idx][1];
112 for ch in 0..channels {
113 pred[ch].delta = i32::from(br.read_u16le()?);
115 for ch in 0..channels {
116 let samp = br.read_u16le()? as i16;
117 pred[ch].sample1 = i32::from(samp);
121 for ch in 0..channels {
122 let samp = br.read_u16le()? as i16;
123 pred[ch].sample2 = i32::from(samp);
128 while br.left() > 0 {
129 let idx = br.read_byte()?;
130 dst[off[0]] = pred[0].expand_nibble(idx >> 4);
132 dst[off[0]] = pred[0].expand_nibble(idx & 0xF);
136 while br.left() > 0 {
137 let idx = br.read_byte()?;
138 dst[off[0]] = pred[0].expand_nibble(idx >> 4);
140 dst[off[1]] = pred[1].expand_nibble(idx & 0xF);
145 let mut frm = NAFrame::new_from_pkt(pkt, info.replace_info(NACodecTypeInfo::Audio(self.ainfo)), abuf);
146 frm.set_duration(Some(nsamples as u64));
147 frm.set_keyframe(false);
150 Err(DecoderError::InvalidData)
153 fn flush(&mut self) {
157 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
158 Box::new(MSADPCMDecoder::new())
163 use nihav_core::codecs::RegisteredDecoders;
164 use nihav_core::demuxers::RegisteredDemuxers;
165 use nihav_codec_support::test::dec_video::*;
166 use crate::ms_register_all_codecs;
167 use nihav_commonfmt::generic_register_all_demuxers;
170 let mut dmx_reg = RegisteredDemuxers::new();
171 generic_register_all_demuxers(&mut dmx_reg);
172 let mut dec_reg = RegisteredDecoders::new();
173 ms_register_all_codecs(&mut dec_reg);
175 test_decoding("avi", "ms-adpcm", "assets/MS/dance.avi", None, &dmx_reg, &dec_reg,
176 ExpectedTestResult::MD5([0x9d6619e1, 0x60d83560, 0xfe5c1fb7, 0xad5d130d]));