switch to better FFT interface and more flexible FFT implementation
[nihav.git] / nihav-commonfmt / src / codecs / atrac3.rs
CommitLineData
38953fb5
KS
1use nihav_core::formats::*;
2use nihav_core::frame::*;
3use nihav_core::codecs::*;
4use nihav_core::io::bitreader::*;
5use nihav_core::io::byteio::*;
6use nihav_core::io::codebook::*;
38953fb5 7use nihav_core::dsp::mdct::IMDCT;
aab478c1
KS
8use std::f32::consts;
9
10#[derive(Clone,Copy,PartialEq)]
11enum Mode {
12 Mono,
13 Stereo,
14 JointStereo,
15}
16
17const ATRAC3_FRAME_SIZE: usize = 1024;
18
19#[derive(Clone,Copy)]
20struct Tone {
21 pos: usize,
22 ncoeffs: usize,
23 coeffs: [f32; 8],
24}
25
26struct GainData {
27 ngains: [usize; 4],
28 gain_lev: [[usize; 8]; 4],
29 gain_loc: [[usize; 8]; 4],
30}
31
32impl GainData {
33 fn new() -> Self {
34 Self {
35 ngains: [0; 4],
36 gain_lev: [[0; 8]; 4],
37 gain_loc: [[0; 8]; 4],
38 }
39 }
40 fn read(&mut self, br: &mut BitReader, bands: usize) -> DecoderResult<()> {
41 self.ngains = [0; 4];
42 for band in 0..bands {
43 self.ngains[band] = br.read(3)? as usize;
44 for i in 0..self.ngains[band] {
45 self.gain_lev[band][i] = br.read(4)? as usize;
46 self.gain_loc[band][i] = br.read(5)? as usize;
47 }
48 }
49 Ok(())
50 }
51}
52
53struct Channel {
54 data: [f32; ATRAC3_FRAME_SIZE],
55 delay: [f32; ATRAC3_FRAME_SIZE],
56 qmf_delay: [f32; 64 * 3],
57
58 bands: usize,
59 block_no: usize,
60
61 gain_data: [GainData; 2],
62
63 subbands: usize,
64 components: usize,
65 ntones: usize,
66 tones: [Tone; 64],
67}
68
69impl Channel {
70 fn new() -> Self {
71 Self {
72 data: [0.0; ATRAC3_FRAME_SIZE],
73 delay: [0.0; ATRAC3_FRAME_SIZE],
74 qmf_delay: [0.0; 64 * 3],
75
76 bands: 0,
77 block_no: 0,
78
79 gain_data: [GainData::new(), GainData::new()],
80
81 subbands: 0,
82 components: 0,
83 ntones: 0,
84 tones: [Tone {pos: 0, ncoeffs: 0, coeffs: [0.0; 8]}; 64],
85 }
86 }
87 fn decode_unit(&mut self, br: &mut BitReader, codebooks: &[Codebook<u8>; 7], scalefactors: &[f32; 64]) -> DecoderResult<()> {
88 self.bands = (br.read(2)? as usize) + 1;
89 self.gain_data[self.block_no].read(br, self.bands)?;
90 self.data = [0.0; ATRAC3_FRAME_SIZE];
91
92 self.ntones = 0;
93 self.components = br.read(5)? as usize;
94 if self.components > 0 {
95 let selector = br.read(2)?;
96 validate!(selector != 2);
97 let mut mode0 = (selector & 1) != 0;
98
99 for _ in 0..self.components {
100 let mut flags: [bool; 4] = [false; 4];
101 for band in 0..self.bands {
102 flags[band] = br.read_bool()?;
103 }
104 let nvals = br.read(3)? as usize;
105 let quant = br.read(3)? as usize;
106 validate!(quant > 1);
107 if selector == 3 {
108 mode0 = br.read_bool()?;
109 }
110 for j in 0..self.bands*4 {
111 if !flags[j >> 2] { continue; }
112 let count = br.read(3)? as usize;
113 validate!(self.ntones + count < 64);
114 for _ in 0..count {
115 let scale_idx = br.read(6)? as usize;
116 let tone = &mut self.tones[self.ntones];
117 tone.pos = (br.read(6)? as usize) + j * 64;
118 tone.ncoeffs = (ATRAC3_FRAME_SIZE - tone.pos).min(nvals + 1);
119 let scale = scalefactors[scale_idx] * ATRAC3_MAX_QUANT[quant];
120 read_coeffs(br, codebooks, &mut tone.coeffs[..tone.ncoeffs], quant, scale, mode0)?;
121 self.ntones += 1;
122 }
123 }
124 }
125 }
126
127 // spectrum
128 let mut quants: [usize; 32] = [0; 32];
129 let mut scf: [usize; 32] = [0; 32];
130 self.subbands = (br.read(5)? as usize) + 1;
131 let mode0 = br.read_bool()?;
132 for i in 0..self.subbands {
133 quants[i] = br.read(3)? as usize;
134 }
135 for i in 0..self.subbands {
136 if quants[i] == 0 { continue; }
137 scf[i] = br.read(6)? as usize;
138 }
139
140 self.data = [0.0; ATRAC3_FRAME_SIZE];
141 for i in 0..self.subbands {
142 if quants[i] == 0 { continue; }
143 let start = ATRAC3_SUBBANDS[i];
144 let end = ATRAC3_SUBBANDS[i + 1];
145 let scale = scalefactors[scf[i]] * ATRAC3_MAX_QUANT[quants[i]];
146 read_coeffs(br, codebooks, &mut self.data[start..end], quants[i], scale, mode0)?;
147 }
148
149 for i in 0..self.ntones {
150 let tone = &self.tones[i];
151 for j in 0..tone.ncoeffs {
152 self.data[tone.pos + j] += tone.coeffs[j];
153 }
154 }
155 Ok(())
156 }
157 fn synth(&mut self, dsp: &mut DSP) {
158 let mut flag = 0;
159 let mut band = 0;
160 for (data, delay) in self.data.chunks_mut(256).zip(self.delay.chunks_mut(256)) {
161 if (flag & 1) != 0 {
162 for i in 0..128 {
163 let t0 = data[i];
164 let t1 = data[255 - i];
165 data[i] = t1;
166 data[255 - i] = t0;
167 }
168 }
169 dsp.synth_band(data);
170 dsp.apply_gains(data, delay, &mut self.gain_data, self.block_no, band);
171 delay.copy_from_slice(&dsp.tmp[256..512]);
172 flag ^= 1;
173 band += 1;
174 }
175 self.block_no ^= 1;
176 }
177 fn do_qmf(&mut self, dsp: &mut DSP, dst: &mut [f32]) {
178 let mut qchunks = self.qmf_delay.chunks_mut(64);
179 let qmf0 = qchunks.next().unwrap();
180 let qmf1 = qchunks.next().unwrap();
181 let qmf2 = qchunks.next().unwrap();
182 {
183 let mut tchunks = self.data.chunks_mut(512);
184 let tmp0 = tchunks.next().unwrap();
185 let tmp1 = tchunks.next().unwrap();
186 dsp.do_qmf(tmp0, qmf0, false);
187 dsp.do_qmf(tmp1, qmf1, true);
188 }
189 dsp.do_qmf_out(dst, &self.data, qmf2);
190 }
191}
192
193const ATRAC3_DEFAULT_DELAY: usize = 2190;
194const ATRAC3_WEIGHTING_DELAYS: [u8; 6] = [ 0, 7, 0, 7, 0, 7 ];
195
196fn read_coeffs(br: &mut BitReader, cb: &[Codebook<u8>; 7], dst: &mut [f32], quant: usize, scale: f32, mode0: bool) -> DecoderResult<()> {
197 if mode0 {
198 read_coeffs_mode0(br, dst, quant, scale)
199 } else if quant == 1 {
200 read_coeffs_mode1(br, &cb[0], dst, scale)
201 } else {
202 read_coeffs_other(br, &cb[quant - 1], dst, scale)
203 }
204}
205
206const ATRAC3_MODE0_CB: [f32; 4] = [ 0.0, 1.0, -2.0, -1.0 ];
207const ATRAC3_MODE0_BITS: [u8; 8] = [ 0, 4, 3, 3, 4, 4, 5, 6 ];
208
209fn read_coeffs_mode0(br: &mut BitReader, dst: &mut [f32], quant: usize, scale: f32) -> DecoderResult<()> {
210 let bits = ATRAC3_MODE0_BITS[quant];
211 if bits > 0 {
212 for i in 0..dst.len() {
213 let val = br.read_s(bits)? as f32;
214 dst[i] = val * scale;
215 }
216 } else {
217 for i in (0..dst.len()).step_by(2) {
218 let val = br.read(4)? as usize;
219 dst[i + 0] = ATRAC3_MODE0_CB[val >> 2] * scale;
220 dst[i + 1] = ATRAC3_MODE0_CB[val & 3] * scale;
221 }
222 }
223 Ok(())
224}
225
226const ATRAC3_MODE1_CB: [f32; 9 * 2] = [
227 0.0, 0.0,
228 0.0, 1.0,
229 0.0, -1.0,
230 1.0, 0.0,
231 -1.0, 0.0,
232 1.0, 1.0,
233 1.0, -1.0,
234 -1.0, 1.0,
235 -1.0, -1.0
236];
237
238fn read_coeffs_mode1(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], scale: f32) -> DecoderResult<()> {
239 for i in (0..dst.len()).step_by(2) {
240 let val = br.read_cb(cb)? as usize;
241 dst[i + 0] = ATRAC3_MODE1_CB[val * 2 + 0] * scale;
242 dst[i + 1] = ATRAC3_MODE1_CB[val * 2 + 1] * scale;
243 }
244 Ok(())
245}
246
247fn read_coeffs_other(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], scale: f32) -> DecoderResult<()> {
248 for i in 0..dst.len() {
249 let val = (br.read_cb(cb)? as i8) + 1;
250 let sign = (val & 1) != 0;
251 let coef = (if sign { -(val >> 1) } else { val >> 1 }) as f32;
252 dst[i] = coef * scale;
253 }
254 Ok(())
255}
256
257struct DSP {
258 imdct: IMDCT,
259 window: [f32; 512],
260 gain_tab: [f32; 16],
261 gain_tab2: [f32; 32],
262 tmp: [f32; ATRAC3_FRAME_SIZE + 64],
263}
264
265impl DSP {
266 fn new() -> Self {
267 let mut gain_tab: [f32; 16] = [0.0; 16];
268 let mut gain_tab2: [f32; 32] = [0.0; 32];
269
270 for i in 0..16 {
271 gain_tab[i] = 2.0f32.powf(4.0 - (i as f32));
272 }
273 for i in 0..32 {
274 gain_tab2[i] = 2.0f32.powf(((i as f32) - 15.0) * -0.125);
275 }
276
277 let mut tmpw: [f32; 256] = [0.0; 256];
278 for i in 0..tmpw.len() {
279 tmpw[i] = (((((i as f32) + 0.5) / 256.0 - 0.5) * consts::PI).sin() + 1.0) * 0.5;
280 }
281
282 let mut window: [f32; 512] = [0.0; 512];
283 for i in 0..tmpw.len() {
284 let w = tmpw[i] / (tmpw[i] * tmpw[i] + tmpw[255 - i] * tmpw[255 - i]);
285 window[i] = w;
286 window[512 - 1 - i] = w;
287 }
1a151e53 288
aab478c1 289 Self {
9e78289c 290 imdct: IMDCT::new(512, false),
aab478c1
KS
291 tmp: [0.0; ATRAC3_FRAME_SIZE + 64],
292 gain_tab, gain_tab2, window,
293 }
294 }
295 fn synth_band(&mut self, src: &[f32]) {
296 let dst = &mut self.tmp;
297 self.imdct.imdct(src, dst);
298 for i in 0..512 {
299 dst[i] *= self.window[i];
300 }
301 }
302 fn apply_gains(&mut self, dst: &mut [f32], delay: &[f32], gain_data: &mut [GainData; 2], block_no: usize, band: usize) {
303 let prev_ngains = gain_data[block_no ^ 1].ngains[band];
304 let gain1 = if gain_data[block_no].ngains[band] > 0 {
305 self.gain_tab[gain_data[block_no].gain_lev[band][0]]
306 } else { 1.0 };
307
308 if prev_ngains == 0 {
309 for i in 0..256 {
310 dst[i] = self.tmp[i] * gain1 + delay[i];
311 }
312 return;
313 }
314
315 gain_data[block_no ^ 1].gain_lev[band][prev_ngains] = 4;
316 gain_data[block_no ^ 1].gain_loc[band][prev_ngains] = 32;
317
318 let mut off = 0;
319 for i in 0..prev_ngains {
320 let start = gain_data[block_no ^ 1].gain_loc[band][i] * 8;
321 let end = start + 8;
322
323 let mut gain2 = self.gain_tab [gain_data[block_no ^ 1].gain_lev[band][i]];
324 let gain_inc = self.gain_tab2[gain_data[block_no ^ 1].gain_lev[band][i + 1] + 15 -
325 gain_data[block_no ^ 1].gain_lev[band][i]];
326
327 while off < start {
328 dst[off] = (self.tmp[off] * gain1 + delay[off]) * gain2;
329 off += 1;
330 }
331 while off < end {
332 dst[off] = (self.tmp[off] * gain1 + delay[off]) * gain2;
333 gain2 *= gain_inc;
334 off += 1;
335 }
336 }
337 for i in off..256 {
338 dst[i] = self.tmp[i] * gain1 + delay[i];
339 }
340 }
341 fn qmf_prepare(&mut self, src: &[f32], delay: &[f32], size: usize, swap: bool) {
342 for i in 0..46 {
343 self.tmp[i] = delay[i];
344 }
345 let (s0, s1) = if !swap {
346 (&src[0..], &src[size/2..])
347 } else {
348 (&src[size/2..], &src[0..])
349 };
350 for i in (0..size).step_by(4) {
351 self.tmp[46 + i + 0] = s0[i / 2 + 0] + s1[i / 2 + 0];
352 self.tmp[46 + i + 1] = s0[i / 2 + 0] - s1[i / 2 + 0];
353 self.tmp[46 + i + 2] = s0[i / 2 + 1] + s1[i / 2 + 1];
354 self.tmp[46 + i + 3] = s0[i / 2 + 1] - s1[i / 2 + 1];
355 }
356 }
357 fn qmf_synth(&mut self, dst: &mut [f32], size: usize) {
358 for i in (0..size).step_by(2) {
359 let mut acc0 = 0.0;
360 let mut acc1 = 0.0;
361
362 for j in (0..ATRAC3_QMF_FILTER.len()).step_by(2) {
363 acc0 += self.tmp[i + j + 0] * ATRAC3_QMF_FILTER[j + 0];
364 acc1 += self.tmp[i + j + 1] * ATRAC3_QMF_FILTER[j + 1];
365 }
366 dst[i + 0] = acc1 * consts::SQRT_2 / 256.0;
367 dst[i + 1] = acc0 * consts::SQRT_2 / 256.0;
368 }
369 }
370 fn do_qmf(&mut self, dst: &mut [f32], delay: &mut [f32], swap: bool) {
371 self.qmf_prepare(dst, delay, 512, swap);
372 self.qmf_synth(dst, 512);
373 for i in 0..46 {
374 delay[i] = self.tmp[512 + i];
375 }
376 }
377 fn do_qmf_out(&mut self, dst: &mut [f32], src: &[f32], delay: &mut [f32]) {
378 self.qmf_prepare(src, delay, 1024, false);
379 self.qmf_synth(dst, 1024);
380 for i in 0..46 {
381 delay[i] = self.tmp[1024 + i];
382 }
383 }
384}
385
386struct Atrac3Decoder {
2422d969 387 info: NACodecInfoRef,
aab478c1
KS
388 channels: usize,
389 chmap: NAChannelMap,
390 samples: usize,
391 mode: Mode,
392 scrambled: bool,
393
394 codebooks: [Codebook<u8>; 7],
395 dsp: DSP,
396 ch_data: [Channel; 2],
397 scalefactors: [f32; 64],
398
399 mci_prev: [usize; 4],
400 mci_cur: [usize; 4],
401 mci_next: [usize; 4],
402
403 weighting_delay: [u8; 6],
404
405 pkt_buf: Vec<u8>,
406}
407
408struct Atrac3CodebookReader {
409 bits: &'static [u8],
410 codes: &'static [u8],
411}
412impl CodebookDescReader<u8> for Atrac3CodebookReader {
413 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
414 fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 }
415 fn sym (&mut self, idx: usize) -> u8 { idx as u8 }
416 fn len(&mut self) -> usize { self.bits.len() }
417}
418
419impl Atrac3Decoder {
420 fn new() -> Self {
421 let mut scalefactors: [f32; 64] = [0.0; 64];
422 for i in 0..scalefactors.len() {
423 scalefactors[i] = 2.0f32.powf(((i as f32) - 15.0) / 3.0);
424 }
425
426 let mut cb0 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[0], bits: ATRAC3_HUFF_BITS[0] };
427 let mut cb1 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[1], bits: ATRAC3_HUFF_BITS[1] };
428 let mut cb2 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[2], bits: ATRAC3_HUFF_BITS[2] };
429 let mut cb3 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[3], bits: ATRAC3_HUFF_BITS[3] };
430 let mut cb4 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[4], bits: ATRAC3_HUFF_BITS[4] };
431 let mut cb5 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[5], bits: ATRAC3_HUFF_BITS[5] };
432 let mut cb6 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[6], bits: ATRAC3_HUFF_BITS[6] };
433 Self {
434 info: NACodecInfo::new_dummy(),
435 chmap: NAChannelMap::new(),
436 channels: 0,
437 samples: 0,
438 mode: Mode::Mono,
439 scrambled: false,
440
441 dsp: DSP::new(),
442 ch_data: [Channel::new(), Channel::new()],
443 codebooks: [Codebook::new(&mut cb0, CodebookMode::MSB).unwrap(),
444 Codebook::new(&mut cb1, CodebookMode::MSB).unwrap(),
445 Codebook::new(&mut cb2, CodebookMode::MSB).unwrap(),
446 Codebook::new(&mut cb3, CodebookMode::MSB).unwrap(),
447 Codebook::new(&mut cb4, CodebookMode::MSB).unwrap(),
448 Codebook::new(&mut cb5, CodebookMode::MSB).unwrap(),
449 Codebook::new(&mut cb6, CodebookMode::MSB).unwrap() ],
450
451 mci_prev: [3; 4],
452 mci_cur: [3; 4],
453 mci_next: [3; 4],
454
455 weighting_delay: ATRAC3_WEIGHTING_DELAYS,
456 pkt_buf: Vec::with_capacity(65536),
457 scalefactors,
458 }
459 }
460 fn rev_matrix(&mut self) {
461 for i in 0..4 {
462 let c0 = self.mci_prev[i];
463 let c1 = self.mci_cur[i];
464 let off;
465 if c0 != c1 {
466 let l0 = ATRAC3_MATRIX_COEFFS[c0 * 2 + 0];
467 let r0 = ATRAC3_MATRIX_COEFFS[c1 * 2 + 0];
468 let l1 = ATRAC3_MATRIX_COEFFS[c0 * 2 + 1];
469 let r1 = ATRAC3_MATRIX_COEFFS[c1 * 2 + 1];
470 for idx in 0..8 {
471 let t0 = self.ch_data[0].data[idx + i * 256];
472 let t1 = self.ch_data[1].data[idx + i * 256];
473 let n1 = t0 * interp(l0, r0, idx) + t1 * interp(l1, r1, idx);
474 self.ch_data[0].data[idx + i * 256] = n1;
475 self.ch_data[1].data[idx + i * 256] = t0 * 2.0 - n1;
476 }
477 off = i * 256 + 8;
478 } else {
479 off = i * 256;
480 }
481 match c1 {
482 0 => {
483 for i in off..256 {
484 let t0 = self.ch_data[0].data[i];
485 let t1 = self.ch_data[1].data[i];
486 self.ch_data[0].data[i] = t1 * 2.0;
487 self.ch_data[1].data[i] = (t0 - t1) * 2.0;
488 }
489 },
490 1 => {
491 for i in off..256 {
492 let t0 = self.ch_data[0].data[i];
493 let t1 = self.ch_data[1].data[i];
494 self.ch_data[0].data[i] = (t0 + t1) * 2.0;
495 self.ch_data[1].data[i] = t1 * -2.0;
496 }
497 },
498 _ => {
499 for i in off..256 {
500 let t0 = self.ch_data[0].data[i];
501 let t1 = self.ch_data[1].data[i];
502 self.ch_data[0].data[i] = t0 + t1;
503 self.ch_data[1].data[i] = t0 - t1;
504 }
505 },
506 };
507 }
508 }
509 fn weigh_channels(&mut self) {
510 if (self.weighting_delay[1] == 7) && (self.weighting_delay[3] == 7) { return; }
511 let pw: [f32; 2];
512 if self.weighting_delay[1] == 7 {
513 pw = [1.0; 2];
514 } else {
515 let w = (self.weighting_delay[1] as f32) / 7.0;
516 let iw = (2.0 - w * w).sqrt();
517 if self.weighting_delay[0] == 0 {
518 pw = [w, iw];
519 } else {
520 pw = [iw, w];
521 }
522 }
523 let cw: [f32; 2];
524 if self.weighting_delay[3] == 7 {
525 cw = [1.0; 2];
526 } else {
527 let w = (self.weighting_delay[3] as f32) / 7.0;
528 let iw = (2.0 - w * w).sqrt();
529 if self.weighting_delay[2] == 0 {
530 cw = [w, iw];
531 } else {
532 cw = [iw, w];
533 }
534 }
535
536 for i in 0..4 {
537 let off = i * 256;
538 for j in 0..8 {
539 self.ch_data[0].data[off + j] *= interp(pw[0], pw[1], j);
540 self.ch_data[1].data[off + j] *= interp(pw[0], pw[1], j);
541 }
542 for j in 8..256 {
543 self.ch_data[0].data[off + j] *= cw[0];
544 self.ch_data[1].data[off + j] *= cw[1];
545 }
546 }
547 }
548}
549
550fn interp(a: f32, b: f32, pos: usize) -> f32 {
551 a + ((pos as f32) / 8.0) * (b - a)
552}
553
554impl NADecoder for Atrac3Decoder {
01613464 555 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
aab478c1
KS
556 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
557 self.info = info.clone();
558 let edata = info.get_extradata().unwrap();
559 validate!(edata.len() >= 4);
560
561 let mut mr = MemoryReader::new_read(&edata);
562 let mut br = ByteReader::new(&mut mr);
563
564 match edata.len() {
565 10 => {
566 let version = br.read_u32be()?;
567 validate!(version == 4);
568 self.samples = br.read_u16be()? as usize;
569 let delay = br.read_u16be()? as usize;
570 validate!(delay == ATRAC3_DEFAULT_DELAY);
571 let mode = br.read_u16be()?;
572 self.mode = match mode {
573 0 => Mode::Mono,
574 2 => Mode::Stereo,
575 0x12 => Mode::JointStereo,
576 _ => return Err(DecoderError::InvalidData),
577 };
578 self.channels = if self.mode == Mode::Mono { 1 } else { 2 };
579 self.scrambled = true;
580 },
581 14 | 16 => {
582 if edata.len() == 16 { br.read_skip(2)?; }
583 self.samples = br.read_u32be()? as usize;
584 let mode = br.read_u16be()?;
585 self.mode = if mode != 0 { Mode::JointStereo } else { Mode::Stereo };
586 self.channels = 2;
587 br.read_skip(2)?;
588 let ffactor = br.read_u16be()? as usize;
589 validate!((ffactor > 0) && (ffactor <= 16));
590 // calculate block_align / channels / ffactor, validate it's 96/152/192
591 },
592 _ => { return Err(DecoderError::InvalidData) }
593 };
594 validate!(self.samples == ATRAC3_FRAME_SIZE * self.channels);
595 if self.mode == Mode::Mono {
596 self.chmap.add_channel(NAChannelType::C);
597 } else {
598 self.chmap.add_channel(NAChannelType::L);
599 self.chmap.add_channel(NAChannelType::R);
600 }
601 let ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), self.channels as u8,
602 SND_F32P_FORMAT, self.samples);
603 self.info = info.replace_info(NACodecTypeInfo::Audio(ainfo));
604 Ok(())
605 } else {
606 Err(DecoderError::InvalidData)
607 }
608 }
01613464 609 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
aab478c1
KS
610 let info = pkt.get_stream().get_info();
611 validate!(info.get_properties().is_audio());
612 let pktbuf = pkt.get_buffer();
613 validate!(pktbuf.len() > 5);
614
615 let frame_size = pktbuf.len();
616 self.pkt_buf.resize(frame_size, 0);
617 if self.scrambled {
618 for (i, s) in pktbuf.iter().enumerate() {
619 self.pkt_buf[i] = s ^ ATRAC3_XOR_KEY[i & 3];
620 }
621 } else {
622 let dst = &mut self.pkt_buf[0..frame_size];
623 dst.copy_from_slice(pktbuf.as_slice());
624 }
625
626 {
627 let mut br = BitReader::new(self.pkt_buf.as_slice(), frame_size, BitReaderMode::BE);
628 let id = br.read(6)?;
629 validate!(id == 0x28);
630 self.ch_data[0].decode_unit(&mut br, &self.codebooks, &self.scalefactors)?;
631 self.ch_data[0].synth(&mut self.dsp);
632 }
633 if self.channels == 2 {
634 let off;
635 if self.mode == Mode::JointStereo {
636 for i in 0..frame_size / 2 {
637 let b0 = self.pkt_buf[i];
638 let b1 = self.pkt_buf[frame_size - i - 1];
639 self.pkt_buf[i] = b1;
640 self.pkt_buf[frame_size - i - 1] = b0;
641 }
642 let mut i = 0;
643 while (i < frame_size) && (self.pkt_buf[i] == 0xF8) { i += 1; }
644 validate!(frame_size - i > 4);
645 off = i;
646 } else {
647 off = frame_size / 2;
648 }
649 let mut br = BitReader::new(&self.pkt_buf[off..], frame_size - off, BitReaderMode::BE);
650 if self.mode == Mode::JointStereo {
651 let id = br.read(2)?;
652 validate!(id == 0x3);
653 } else {
654 let id = br.read(6)?;
655 validate!(id == 0x28);
656 }
657 if self.mode == Mode::JointStereo {
658 for i in 0..self.weighting_delay.len() - 2 {
659 self.weighting_delay[i] = self.weighting_delay[i + 2];
660 }
661 self.weighting_delay[4] = br.read(1)? as u8;
662 self.weighting_delay[5] = br.read(3)? as u8;
663 self.mci_prev = self.mci_cur;
664 self.mci_cur = self.mci_next;
665 for i in 0..4 {
666 self.mci_next[i] = br.read(2)? as usize;
667 }
668 }
669 self.ch_data[1].decode_unit(&mut br, &self.codebooks, &self.scalefactors)?;
670 self.ch_data[1].synth(&mut self.dsp);
671 }
672 if self.mode == Mode::JointStereo {
673 self.rev_matrix();
674 self.weigh_channels();
675 }
676
677 let ainfo = self.info.get_properties().get_audio_info().unwrap();
678
b70cc006 679 let abuf = alloc_audio_buffer(ainfo, ATRAC3_FRAME_SIZE, self.chmap.clone())?;
aab478c1 680 let mut adata = abuf.get_abuf_f32().unwrap();
1a967e6b 681 let output = adata.get_data_mut().unwrap();
aab478c1
KS
682
683 for ch in 0..self.channels {
684 let dpos = abuf.get_offset(ch);
685 self.ch_data[ch].do_qmf(&mut self.dsp, &mut output[dpos..][..ATRAC3_FRAME_SIZE]);
686 }
687
688 let mut frm = NAFrame::new_from_pkt(pkt, self.info.replace_info(NACodecTypeInfo::Audio(ainfo)), abuf);
689 frm.set_keyframe(true);
171860fc 690 Ok(frm.into_ref())
aab478c1
KS
691 }
692}
693
694pub fn get_decoder() -> Box<NADecoder> {
695 Box::new(Atrac3Decoder::new())
696}
697
698#[cfg(test)]
699mod test {
4f6124ac
KS
700 use nihav_core::codecs::RegisteredDecoders;
701 use nihav_core::demuxers::RegisteredDemuxers;
702 use nihav_core::test::dec_video::test_decode_audio;
703 use crate::codecs::generic_register_all_codecs;
704 use nihav_realmedia::demuxers::realmedia_register_all_demuxers;
aab478c1
KS
705 #[test]
706 fn test_atrac3() {
4f6124ac
KS
707 let mut dmx_reg = RegisteredDemuxers::new();
708 realmedia_register_all_demuxers(&mut dmx_reg);
709 let mut dec_reg = RegisteredDecoders::new();
710 generic_register_all_codecs(&mut dec_reg);
711
aab478c1
KS
712 let file = "assets/RV/rv30_atrc_384x208_realproducer_plus_8.51.rm";
713// let file = "assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm";
4f6124ac 714 test_decode_audio("realmedia", file, Some(12000), "atrac3", &dmx_reg, &dec_reg);
aab478c1
KS
715 }
716}
717
718const ATRAC3_XOR_KEY: [u8; 4] = [ 0x53, 0x7F, 0x61, 0x03 ];
719
720const ATRAC3_HUFF_CODES: [&[u8]; 7] = [
721 &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x1C, 0x1D, 0x1E, 0x1F ],
722 &[ 0x00, 0x04, 0x05, 0x06, 0x07 ],
723 &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F ],
724 &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x1C, 0x1D, 0x1E, 0x1F ], // same as 0
725 &[ 0x00, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x1C, 0x1D, 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x0D ],
726 &[ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x14,
727 0x15, 0x16, 0x17, 0x18, 0x19, 0x34, 0x35, 0x36,
728 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x78, 0x79, 0x7A,
729 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x08, 0x09 ],
730 &[ 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
731 0x0F, 0x10, 0x11, 0x24, 0x25, 0x26, 0x27, 0x28,
732 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
733 0x31, 0x32, 0x33, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
734 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
735 0x75, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2,
736 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
737 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x02, 0x03 ]
738];
739const ATRAC3_HUFF_BITS: [&[u8]; 7] = [
740 &[ 1, 3, 3, 4, 4, 5, 5, 5, 5 ],
741 &[ 1, 3, 3, 3, 3 ],
742 &[ 1, 3, 3, 4, 4, 4, 4 ],
743 &[ 1, 3, 3, 4, 4, 5, 5, 5, 5 ],
744 &[ 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 4, 4 ],
745 &[ 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4 ],
746 &[ 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
747 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4 ],
748];
749
750const ATRAC3_MAX_QUANT: [f32; 8] = [ 0.0, 1.0/1.5, 1.0/2.5, 1.0/3.5, 1.0/4.5, 1.0/7.5, 1.0/15.5, 1.0/31.5 ];
751
752const ATRAC3_SUBBANDS: [usize; 32 + 1] = [
753 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176,
754 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896,
755 1024
756];
757
758const ATRAC3_MATRIX_COEFFS: [f32; 8] = [ 0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0 ];
759
760const ATRAC3_QMF_FILTER: [f32; 48] = [
761 -0.000029238139, -0.000184109580, -0.000112315138, 0.000602345390,
762 0.000484503806, -0.001705877949, -0.001041114796, 0.004068033770,
763 0.001566677820, -0.008430772461, -0.001512299757, 0.015680588782,
764 -0.000122339843, -0.026883240789, 0.004925364163, 0.043472178280,
765 -0.015603342094, -0.068180441856, 0.037618979812, 0.108652018011,
766 -0.087192758918, -0.198768734932, 0.264158189297, 0.928483188152,
767 0.928483188152, 0.264158189297, -0.198768734932, -0.087192758918,
768 0.108652018011, 0.037618979812, -0.068180441856, -0.015603342094,
769 0.043472178280, 0.004925364163, -0.026883240789, -0.000122339843,
770 0.015680588782, -0.001512299757, -0.008430772461, 0.001566677820,
771 0.004068033770, -0.001041114796, -0.001705877949, 0.000484503806,
772 0.000602345390, -0.000112315138, -0.000184109580, -0.000029238139
773];