add nihav-llaudio crate with FLAC, Monkey's Audio, TTA and WavPack support
[nihav.git] / nihav-llaudio / src / codecs / ape.rs
1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_core::io::bitreader::*;
4
5 use super::apepred::*;
6 use super::apereader::*;
7
8 struct APEDecoder {
9 ainfo: NAAudioInfo,
10 chmap: NAChannelMap,
11 version: u16,
12 decode_mono: fn(&mut Coder, &mut [i32]) -> DecoderResult<()>,
13 decode_stereo: fn(&mut Coder, &mut [i32], &mut [i32]) -> DecoderResult<()>,
14 is_stereo: bool,
15 left: Vec<i32>,
16 right: Vec<i32>,
17 fmode: FilterMode,
18 data: Vec<u8>,
19 blocksperframe: usize,
20 }
21
22 impl APEDecoder {
23 fn new() -> Self {
24 Self {
25 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
26 chmap: NAChannelMap::new(),
27 version: 0,
28 decode_mono: decode_mono_dummy,
29 decode_stereo: decode_stereo_dummy,
30 is_stereo: false,
31 left: Vec::new(),
32 right: Vec::new(),
33 fmode: FilterMode::None,
34 data: Vec::new(),
35 blocksperframe: 0,
36 }
37 }
38 }
39
40 impl NADecoder for APEDecoder {
41 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
42 if let NACodecTypeInfo::Audio(_ainfo) = info.get_properties() {
43 if let Some(buf) = info.get_extradata() {
44 let mut mr = MemoryReader::new_read(&buf);
45 let mut br = ByteReader::new(&mut mr);
46 let version = br.read_u16le()?;
47 let compression = br.read_u16le()?;
48 let _flags = br.read_u16le()?;
49 let channels = br.read_byte()?;
50 let bits = br.read_byte()?;
51 let srate = br.read_u32le()?;
52 let blocksperframe = br.read_u32le()? as usize;
53
54 validate!(channels > 0);
55 validate!(bits > 0 && bits <= 32);
56 validate!((compression % 1000) == 0 && compression > 0 && compression <= 5000);
57 validate!(compression < 5000 || version >= 3930);
58 if bits != 16 {
59 return Err(DecoderError::NotImplemented);
60 }
61 if version > 3990 {
62 return Err(DecoderError::NotImplemented);
63 }
64
65 self.version = version;
66 self.blocksperframe = blocksperframe;
67 self.is_stereo = channels == 2;
68 self.left.resize(blocksperframe, 0);
69 if self.is_stereo {
70 self.right.resize(blocksperframe, 0);
71 }
72
73 self.decode_mono = if version >= 3990 {
74 decode_mono_3990
75 } else if version >= 3910 {
76 decode_mono_3910
77 } else if version >= 3900 {
78 decode_mono_3900
79 } else if version >= 3890 {
80 decode_mono_3890
81 } else if version >= 3860 {
82 decode_mono_3860
83 } else {
84 decode_mono_0000
85 };
86 self.decode_stereo = if version >= 3990 {
87 decode_stereo_3990
88 } else if version >= 3930 {
89 decode_stereo_3930
90 } else if version >= 3910 {
91 decode_stereo_3910
92 } else if version >= 3900 {
93 decode_stereo_3900
94 } else if version >= 3890 {
95 decode_stereo_3890
96 } else if version >= 3860 {
97 decode_stereo_3860
98 } else {
99 decode_stereo_0000
100 };
101 self.fmode = FilterMode::new(version, compression);
102
103 self.chmap = if channels == 1 {
104 NAChannelMap::from_str("C").unwrap()
105 } else if channels == 2 {
106 NAChannelMap::from_str("L,R").unwrap()
107 } else {
108 return Err(DecoderError::NotImplemented);
109 };
110 self.ainfo = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, 4602);
111 Ok(())
112 } else {
113 Err(DecoderError::InvalidData)
114 }
115 } else {
116 Err(DecoderError::InvalidData)
117 }
118 }
119 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
120 let info = pkt.get_stream().get_info();
121 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
122 let pktbuf = pkt.get_buffer();
123 validate!(pktbuf.len() > 9);
124
125 let nblocks = read_u32le(&pktbuf[0..])? as usize;
126 validate!(nblocks > 0);
127 let bits = u32::from(pktbuf[4]);
128 validate!(bits < 32);
129 self.data.truncate(0);
130 self.data.reserve((pktbuf.len() & !3) + 2);
131 for word in pktbuf[8..].chunks_exact(4) {
132 self.data.push(word[3]);
133 self.data.push(word[2]);
134 self.data.push(word[1]);
135 self.data.push(word[0]);
136 }
137 if self.version < 3950 {
138 self.data.push(0);
139 self.data.push(0);
140 }
141
142 let (mut coder, ref_crc, fflags) = if self.version < 3900 {
143 let mut br = BitReader::new(&self.data, BitReaderMode::BE);
144 br.skip(bits)?;
145 let mut crc = br.read(32)?;
146 let fflags = if self.version >= 3830 && (crc & 0x80000000) != 0 {
147 crc ^= 0x80000000;
148 br.read(32)?
149 } else {
150 0
151 };
152 (Coder::Rice(RiceCoder::new(br)), crc, fflags)
153 } else {
154 let mut boff = (bits / 8) as usize;
155 let mut crc = read_u32be(&self.data[boff..])?;
156 boff += 4;
157 let fflags = if (crc & 0x80000000) != 0 {
158 crc ^= 0x80000000;
159 let flg = read_u32be(&self.data[boff..])?;
160 boff += 4;
161 flg
162 } else {
163 0
164 };
165 // it ignores first byte anyway
166 (Coder::Range(RangeCoder::new(&self.data[boff + 1..])), crc, fflags)
167 };
168 self.left.resize(nblocks, 0);
169 if self.is_stereo {
170 self.right.resize(nblocks, 0);
171 }
172 if (fflags & 3) == 0 {
173 if !self.is_stereo || (fflags & 4) != 0 {
174 (self.decode_mono)(&mut coder, &mut self.left)?;
175 self.fmode.filter_mono(&mut self.left);
176
177 if (fflags & 4) != 0 {
178 self.right.copy_from_slice(&self.left);
179 }
180 } else {
181 (self.decode_stereo)(&mut coder, &mut self.left, &mut self.right)?;
182 self.fmode.filter_stereo(&mut self.left, &mut self.right);
183 }
184 }
185
186 if self.version >= 0x3990 || nblocks == self.blocksperframe {
187 let mut crc = 0xFFFFFFFF;
188 if !self.is_stereo {
189 for el in self.left.iter() {
190 let byte1 = *el as u8;
191 let byte0 = (*el >> 8) as u8;
192 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
193 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
194 }
195 } else {
196 for (l, r) in self.left.iter().zip(self.right.iter()) {
197 let byte1 = *l as u8;
198 let byte0 = (*l >> 8) as u8;
199 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
200 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
201 let byte1 = *r as u8;
202 let byte0 = (*r >> 8) as u8;
203 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
204 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
205 }
206 }
207 crc = !crc;
208 if self.version >= 3830 {
209 crc >>= 1;
210 }
211 if crc != ref_crc {
212 return Err(DecoderError::ChecksumError);
213 }
214 }
215
216 let abuf = alloc_audio_buffer(self.ainfo, nblocks, self.chmap.clone())?;
217 let mut adata = abuf.get_abuf_i16().unwrap();
218 let off1 = adata.get_offset(1);
219 let dst = adata.get_data_mut().unwrap();
220 let (left, right) = dst.split_at_mut(off1);
221 for (dst, src) in left.iter_mut().zip(self.left.iter()) {
222 *dst = *src as i16;
223 }
224 if self.is_stereo {
225 for (dst, src) in right.iter_mut().zip(self.right.iter()) {
226 *dst = *src as i16;
227 }
228 }
229
230 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
231 frm.set_duration(Some(nblocks as u64));
232 Ok(frm.into_ref())
233 } else {
234 Err(DecoderError::InvalidData)
235 }
236 }
237 fn flush(&mut self) {
238 }
239 }
240
241 impl NAOptionHandler for APEDecoder {
242 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
243 fn set_options(&mut self, _options: &[NAOption]) { }
244 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
245 }
246
247 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
248 Box::new(APEDecoder::new())
249 }
250
251 #[cfg(test)]
252 mod test {
253 use nihav_core::codecs::RegisteredDecoders;
254 use nihav_core::demuxers::RegisteredDemuxers;
255 use nihav_codec_support::test::dec_video::*;
256 use crate::llaudio_register_all_decoders;
257 use crate::llaudio_register_all_demuxers;
258 #[test]
259 fn test_ape_3990() {
260 let mut dmx_reg = RegisteredDemuxers::new();
261 llaudio_register_all_demuxers(&mut dmx_reg);
262 let mut dec_reg = RegisteredDecoders::new();
263 llaudio_register_all_decoders(&mut dec_reg);
264
265 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight.ape", Some(3), &dmx_reg, &dec_reg,
266 ExpectedTestResult::MD5([0x569e002b, 0xd93772a9, 0x1cfd81cd, 0xad81319a]));
267 }
268 #[test]
269 fn test_ape_3940() {
270 let mut dmx_reg = RegisteredDemuxers::new();
271 llaudio_register_all_demuxers(&mut dmx_reg);
272 let mut dec_reg = RegisteredDecoders::new();
273 llaudio_register_all_decoders(&mut dec_reg);
274
275 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac394b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
276 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
277 }
278 #[test]
279 fn test_ape_3920() {
280 let mut dmx_reg = RegisteredDemuxers::new();
281 llaudio_register_all_demuxers(&mut dmx_reg);
282 let mut dec_reg = RegisteredDecoders::new();
283 llaudio_register_all_decoders(&mut dec_reg);
284
285 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac392b2-c4000.ape", Some(1), &dmx_reg, &dec_reg,
286 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
287 }
288 #[test]
289 fn test_ape_3910() {
290 let mut dmx_reg = RegisteredDemuxers::new();
291 llaudio_register_all_demuxers(&mut dmx_reg);
292 let mut dec_reg = RegisteredDecoders::new();
293 llaudio_register_all_decoders(&mut dec_reg);
294
295 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac391b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
296 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
297 }
298 #[test]
299 fn test_ape_3890() {
300 let mut dmx_reg = RegisteredDemuxers::new();
301 llaudio_register_all_demuxers(&mut dmx_reg);
302 let mut dec_reg = RegisteredDecoders::new();
303 llaudio_register_all_decoders(&mut dec_reg);
304
305 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac389b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
306 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
307 }
308 #[test]
309 fn test_ape_3880() {
310 let mut dmx_reg = RegisteredDemuxers::new();
311 llaudio_register_all_demuxers(&mut dmx_reg);
312 let mut dec_reg = RegisteredDecoders::new();
313 llaudio_register_all_decoders(&mut dec_reg);
314
315 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac388-c4000.ape", Some(1), &dmx_reg, &dec_reg,
316 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
317 }
318 #[test]
319 fn test_ape_3800() {
320 let mut dmx_reg = RegisteredDemuxers::new();
321 llaudio_register_all_demuxers(&mut dmx_reg);
322 let mut dec_reg = RegisteredDecoders::new();
323 llaudio_register_all_decoders(&mut dec_reg);
324
325 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac380-c4000.ape", Some(1), &dmx_reg, &dec_reg,
326 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
327 }
328 }
329
330 const CRC32_TAB: [u32; 256] = [
331 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
332 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
333 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
334 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
335 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
336 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
337 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
338 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
339 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
340 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
341 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
342 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
343 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
344 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
345 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
346 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
347 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
348 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
349 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
350 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
351 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
352 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
353 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
354 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
355 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
356 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
357 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
358 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
359 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
360 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
361 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
362 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
363 ];