]> git.nihav.org Git - nihav.git/blob - nihav-llaudio/src/codecs/tta.rs
add bytes_left() to NAPacketiser so its internal buffer size can be monitored
[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 test_decoding("tta", "tta", "assets/LLaudio/luckynight.tta", Some(3), &dmx_reg, &dec_reg,
345 ExpectedTestResult::MD5([0xce0fe9c4, 0xa69eefda, 0xe182008c, 0xe941db3f]));
346 }
347 }
348
349 const CRC32_TAB: [u32; 256] = [
350 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
351 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
352 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
353 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
354 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
355 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
356 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
357 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
358 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
359 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
360 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
361 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
362 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
363 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
364 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
365 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
366 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
367 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
368 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
369 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
370 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
371 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
372 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
373 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
374 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
375 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
376 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
377 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
378 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
379 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
380 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
381 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
382 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
383 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
384 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
385 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
386 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
387 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
388 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
389 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
390 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
391 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
392 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
393 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
394 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
395 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
396 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
397 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
398 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
399 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
400 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
401 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
402 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
403 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
404 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
405 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
406 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
407 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
408 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
409 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
410 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
411 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
412 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
413 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
414 ];