d5130644683e094fdb0e34ba4649041db0cdbcb6
[nihav.git] / nihav-llaudio / src / codecs / tta.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::io::bitreader::*;
4 use nihav_core::io::intcode::*;
5
6 #[derive(Default)]
7 struct Filter {
8 predictor: i32,
9 error: i32,
10 round: i32,
11 shift: u8,
12 qm: [i32; 8],
13 dx: [i32; 8],
14 dl: [i32; 8],
15 }
16
17 impl Filter {
18 fn reset(&mut self, bpp: u8) {
19 const SHIFTS: [u8; 3] = [10, 9, 10];
20 self.shift = SHIFTS[(bpp - 1) as usize];
21 self.round = (1 << self.shift) >> 1;
22 self.error = 0;
23 self.qm = [0; 8];
24 self.dx = [0; 8];
25 self.dl = [0; 8];
26 self.predictor = 0;
27 }
28 fn hybrid_filt(&mut self, delta: i32) -> i32 {
29 if self.error < 0 {
30 for (qm, dx) in self.qm.iter_mut().zip(self.dx.iter()) {
31 *qm -= *dx;
32 }
33 } else if self.error > 0 {
34 for (qm, dx) in self.qm.iter_mut().zip(self.dx.iter()) {
35 *qm += *dx;
36 }
37 }
38
39 let mut sum = self.round;
40 for (dl, qm) in self.dl.iter().zip(self.qm.iter()) {
41 sum = sum.wrapping_add(*dl * *qm);
42 }
43 self.error = delta;
44 let val = (sum >> self.shift) + delta;
45
46 for i in 0..4 {
47 self.dx[i] = self.dx[i + 1];
48 self.dl[i] = self.dl[i + 1];
49 }
50 self.dx[4] = (self.dl[4] >> 30) | 1;
51 self.dx[5] = ((self.dl[5] >> 30) | 2) & !1;
52 self.dx[6] = ((self.dl[6] >> 30) | 2) & !1;
53 self.dx[7] = ((self.dl[7] >> 30) | 4) & !3;
54 self.dl[4] = -self.dl[5];
55 self.dl[5] = -self.dl[6];
56 self.dl[6] = val - self.dl[7];
57 self.dl[7] = val;
58 self.dl[5] += self.dl[6];
59 self.dl[4] += self.dl[5];
60
61 val
62 }
63 fn static_pred(&mut self, bpp: u8, mut val: i32) -> i32 {
64 val += match bpp {
65 0 => ((i64::from(self.predictor) * 15) >> 4) as i32,
66 1 | 2 => ((i64::from(self.predictor) * 31) >> 5) as i32,
67 _ => self.predictor,
68 };
69 self.predictor = val;
70 val
71 }
72 }
73
74 struct RiceDecoder {
75 k: u8,
76 sum: u32,
77 }
78
79 impl RiceDecoder {
80 fn new() -> Self {
81 let k = 10;
82 Self {
83 k, sum: RiceDecoder::limit(k)
84 }
85 }
86 fn reset(&mut self) {
87 self.k = 10;
88 self.sum = RiceDecoder::limit(self.k);
89 }
90 fn limit(k: u8) -> u32 { 1 << (k + 4).min(31) }
91 fn update(&mut self, val: u32) {
92 self.sum -= self.sum >> 4;
93 self.sum += val;
94 if self.k > 0 && self.sum < Self::limit(self.k) {
95 self.k -= 1;
96 } else if self.sum > Self::limit(self.k + 1) {
97 self.k += 1;
98 }
99 }
100 }
101
102 trait Output {
103 fn set(&mut self, val: i32);
104 }
105
106 impl Output for i16 {
107 fn set(&mut self, val: i32) { *self = val as i16; }
108 }
109 impl Output for i32 {
110 fn set(&mut self, val: i32) { *self = val; }
111 }
112
113 struct ChannelDecoder {
114 filt: Filter,
115 rice0: RiceDecoder,
116 rice1: RiceDecoder,
117 offset: usize,
118 sample: i32,
119 }
120
121 impl ChannelDecoder {
122 fn new() -> Self {
123 Self {
124 filt: Filter::default(),
125 rice0: RiceDecoder::new(),
126 rice1: RiceDecoder::new(),
127 offset: 0,
128 sample: 0,
129 }
130 }
131 }
132
133 struct TTADecoder {
134 ainfo: NAAudioInfo,
135 chmap: NAChannelMap,
136 bpp: u8,
137 framelen: u32,
138 nsamples: u32,
139 ch_dec: Vec<ChannelDecoder>,
140 }
141
142 impl TTADecoder {
143 fn new() -> Self {
144 Self {
145 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
146 chmap: NAChannelMap::new(),
147 bpp: 0,
148 framelen: 0,
149 nsamples: 0,
150 ch_dec: Vec::new(),
151 }
152 }
153 fn decode_frame<T: Output>(&mut self, br: &mut BitReader, dst: &mut [T], stride: usize) -> DecoderResult<bool> {
154 for (i, chdec) in self.ch_dec.iter_mut().enumerate() {
155 chdec.offset = i * stride;
156 chdec.rice0.reset();
157 chdec.rice1.reset();
158 chdec.filt.reset(self.bpp);
159 }
160
161 let channels = self.ch_dec.len();
162 let tail_len = self.nsamples % self.framelen;
163
164 for sample in 0..self.framelen {
165 for chdec in self.ch_dec.iter_mut() {
166 let pfx = br.read_code(UintCodeType::UnaryOnes)?;
167 let (k, pfx, level1) = if pfx == 0 {
168 (chdec.rice0.k, 0, false)
169 } else {
170 (chdec.rice1.k, pfx - 1, true)
171 };
172 let mut val = (pfx << k) | br.read(k)?;
173 if level1 {
174 chdec.rice1.update(val);
175 val += 1 << chdec.rice0.k;
176 }
177 chdec.rice0.update(val);
178 let delta = if (val & 1) == 0 {
179 -((val >> 1) as i32)
180 } else {
181 ((val + 1) >> 1) as i32
182 };
183 let hval = chdec.filt.hybrid_filt(delta);
184 chdec.sample = chdec.filt.static_pred(self.bpp, hval);
185 }
186 if channels > 1 {
187 self.ch_dec[channels - 1].sample += self.ch_dec[channels - 2].sample / 2;
188 let mut last = self.ch_dec[channels - 1].sample;
189 for chdec in self.ch_dec.iter_mut().rev().skip(1) {
190 chdec.sample = last - chdec.sample;
191 last = chdec.sample;
192 }
193 }
194 for chdec in self.ch_dec.iter_mut() {
195 dst[chdec.offset].set(chdec.sample);
196 chdec.offset += 1;
197 }
198 if (tail_len > 0) && (sample == tail_len - 1) && (br.left() < 40) {
199 return Ok(false);
200 }
201 }
202
203 Ok(true)
204 }
205 }
206
207 fn check_crc(buf: &[u8]) -> bool {
208 if buf.len() <= 4 {
209 return false;
210 }
211 let mut crc = 0xFFFFFFFF;
212 let ref_crc = read_u32le(&buf[buf.len() - 4..]).unwrap_or(0);
213 for el in buf.iter().take(buf.len() - 4) {
214 crc = CRC32_TAB[(crc as u8 ^ *el) as usize] ^ (crc >> 8);
215 }
216 crc == !ref_crc
217 }
218
219 impl NADecoder for TTADecoder {
220 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
221 if let NACodecTypeInfo::Audio(_ainfo) = info.get_properties() {
222 if let Some(buf) = info.get_extradata() {
223 if !check_crc(&buf) {
224 return Err(DecoderError::ChecksumError);
225 }
226 let mut mr = MemoryReader::new_read(&buf);
227 let mut br = ByteReader::new(&mut mr);
228 let tag = br.read_tag()?;
229 validate!(&tag == b"TTA1");
230 let afmt = br.read_u16le()?;
231 if afmt != 1 {
232 return Err(DecoderError::NotImplemented);
233 }
234 let channels = br.read_u16le()?;
235 validate!(channels > 0 && channels < 256);
236 let bpp = br.read_u16le()?;
237 validate!(bpp > 0 && bpp <= 32);
238 let srate = br.read_u32le()?;
239 validate!(srate > 256 && srate < 1048576);
240 self.nsamples = br.read_u32le()?;
241 validate!(self.nsamples > 0);
242
243 self.framelen = srate * 256 / 245;
244
245 self.chmap = if channels == 1 {
246 NAChannelMap::from_str("C").unwrap()
247 } else if channels == 2 {
248 NAChannelMap::from_str("L,R").unwrap()
249 } else {
250 return Err(DecoderError::NotImplemented);
251 };
252 let fmt = match bpp {
253 8 | 16 => SND_S16P_FORMAT,
254 24 | 32 => SND_S32P_FORMAT,
255 _ => return Err(DecoderError::NotImplemented),
256 };
257 self.bpp = (bpp / 8) as u8;
258 self.ch_dec = Vec::with_capacity(channels as usize);
259 for _ in 0..channels {
260 self.ch_dec.push(ChannelDecoder::new());
261 }
262
263 self.ainfo = NAAudioInfo::new(srate, channels as u8, fmt, self.framelen as usize);
264 Ok(())
265 } else {
266 Err(DecoderError::InvalidData)
267 }
268 } else {
269 Err(DecoderError::InvalidData)
270 }
271 }
272 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
273 let info = pkt.get_stream().get_info();
274 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
275 let pktbuf = pkt.get_buffer();
276 validate!(pktbuf.len() > 4);
277 if !check_crc(&pktbuf) {
278 return Err(DecoderError::ChecksumError);
279 }
280
281 let mut br = BitReader::new(&pktbuf, BitReaderMode::LE);
282
283 let mut abuf = alloc_audio_buffer(self.ainfo, self.framelen as usize, self.chmap.clone())?;
284 let duration = match abuf {
285 NABufferType::AudioI16(ref mut adata) => {
286 let stride = adata.get_stride();
287 let dst = adata.get_data_mut().unwrap();
288 let not_last = self.decode_frame(&mut br, dst, stride)?;
289 if not_last {
290 self.framelen
291 } else {
292 self.nsamples % self.framelen
293 }
294 },
295 NABufferType::AudioI32(ref mut adata) => {
296 let stride = adata.get_stride();
297 let dst = adata.get_data_mut().unwrap();
298 let not_last = self.decode_frame(&mut br, dst, stride)?;
299 if not_last {
300 self.framelen
301 } else {
302 self.nsamples % self.framelen
303 }
304 },
305 _ => unreachable!(),
306 };
307 abuf.truncate_audio(duration as usize);
308
309 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
310 frm.set_duration(Some(u64::from(duration)));
311 Ok(frm.into_ref())
312 } else {
313 Err(DecoderError::InvalidData)
314 }
315 }
316 fn flush(&mut self) {
317 }
318 }
319
320 impl NAOptionHandler for TTADecoder {
321 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
322 fn set_options(&mut self, _options: &[NAOption]) { }
323 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
324 }
325
326 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
327 Box::new(TTADecoder::new())
328 }
329
330 #[cfg(test)]
331 mod test {
332 use nihav_core::codecs::RegisteredDecoders;
333 use nihav_core::demuxers::RegisteredDemuxers;
334 use nihav_codec_support::test::dec_video::*;
335 use crate::llaudio_register_all_decoders;
336 use crate::llaudio_register_all_demuxers;
337 #[test]
338 fn test_tta() {
339 let mut dmx_reg = RegisteredDemuxers::new();
340 llaudio_register_all_demuxers(&mut dmx_reg);
341 let mut dec_reg = RegisteredDecoders::new();
342 llaudio_register_all_decoders(&mut dec_reg);
343
344 // sample: https://samples.mplayerhq.hu/A-codecs/lossless/luckynight.tta
345 test_decoding("tta", "tta", "assets/LLaudio/luckynight.tta", Some(3), &dmx_reg, &dec_reg,
346 ExpectedTestResult::MD5([0xce0fe9c4, 0xa69eefda, 0xe182008c, 0xe941db3f]));
347 }
348 }
349
350 const CRC32_TAB: [u32; 256] = [
351 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
352 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
353 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
354 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
355 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
356 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
357 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
358 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
359 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
360 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
361 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
362 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
363 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
364 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
365 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
366 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
367 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
368 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
369 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
370 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
371 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
372 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
373 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
374 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
375 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
376 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
377 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
378 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
379 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
380 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
381 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
382 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
383 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
384 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
385 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
386 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
387 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
388 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
389 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
390 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
391 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
392 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
393 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
394 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
395 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
396 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
397 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
398 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
399 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
400 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
401 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
402 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
403 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
404 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
405 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
406 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
407 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
408 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
409 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
410 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
411 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
412 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
413 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
414 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
415 ];