]> git.nihav.org Git - nihav.git/blame - nihav-commonfmt/src/codecs/atrac3.rs
indeo3enc: fix always enabled frame recompression
[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::*;
b4d5b851 7use nihav_codec_support::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;
c83013a1 159 for (band, (data, delay)) in self.data.chunks_mut(256).zip(self.delay.chunks_mut(256)).enumerate() {
aab478c1
KS
160 if (flag & 1) != 0 {
161 for i in 0..128 {
162 let t0 = data[i];
163 let t1 = data[255 - i];
164 data[i] = t1;
165 data[255 - i] = t0;
166 }
167 }
168 dsp.synth_band(data);
169 dsp.apply_gains(data, delay, &mut self.gain_data, self.block_no, band);
170 delay.copy_from_slice(&dsp.tmp[256..512]);
171 flag ^= 1;
aab478c1
KS
172 }
173 self.block_no ^= 1;
174 }
175 fn do_qmf(&mut self, dsp: &mut DSP, dst: &mut [f32]) {
176 let mut qchunks = self.qmf_delay.chunks_mut(64);
177 let qmf0 = qchunks.next().unwrap();
178 let qmf1 = qchunks.next().unwrap();
179 let qmf2 = qchunks.next().unwrap();
180 {
181 let mut tchunks = self.data.chunks_mut(512);
182 let tmp0 = tchunks.next().unwrap();
183 let tmp1 = tchunks.next().unwrap();
184 dsp.do_qmf(tmp0, qmf0, false);
185 dsp.do_qmf(tmp1, qmf1, true);
186 }
187 dsp.do_qmf_out(dst, &self.data, qmf2);
188 }
189}
190
191const ATRAC3_DEFAULT_DELAY: usize = 2190;
192const ATRAC3_WEIGHTING_DELAYS: [u8; 6] = [ 0, 7, 0, 7, 0, 7 ];
193
194fn read_coeffs(br: &mut BitReader, cb: &[Codebook<u8>; 7], dst: &mut [f32], quant: usize, scale: f32, mode0: bool) -> DecoderResult<()> {
195 if mode0 {
196 read_coeffs_mode0(br, dst, quant, scale)
197 } else if quant == 1 {
198 read_coeffs_mode1(br, &cb[0], dst, scale)
199 } else {
200 read_coeffs_other(br, &cb[quant - 1], dst, scale)
201 }
202}
203
204const ATRAC3_MODE0_CB: [f32; 4] = [ 0.0, 1.0, -2.0, -1.0 ];
205const ATRAC3_MODE0_BITS: [u8; 8] = [ 0, 4, 3, 3, 4, 4, 5, 6 ];
206
207fn read_coeffs_mode0(br: &mut BitReader, dst: &mut [f32], quant: usize, scale: f32) -> DecoderResult<()> {
208 let bits = ATRAC3_MODE0_BITS[quant];
209 if bits > 0 {
c83013a1 210 for el in dst.iter_mut() {
aab478c1 211 let val = br.read_s(bits)? as f32;
c83013a1 212 *el = val * scale;
aab478c1
KS
213 }
214 } else {
c83013a1 215 for out in dst.chunks_mut(2) {
aab478c1 216 let val = br.read(4)? as usize;
c83013a1
KS
217 out[0] = ATRAC3_MODE0_CB[val >> 2] * scale;
218 out[1] = ATRAC3_MODE0_CB[val & 3] * scale;
aab478c1
KS
219 }
220 }
221 Ok(())
222}
223
224const ATRAC3_MODE1_CB: [f32; 9 * 2] = [
225 0.0, 0.0,
226 0.0, 1.0,
227 0.0, -1.0,
228 1.0, 0.0,
229 -1.0, 0.0,
230 1.0, 1.0,
231 1.0, -1.0,
232 -1.0, 1.0,
233 -1.0, -1.0
234];
235
236fn read_coeffs_mode1(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], scale: f32) -> DecoderResult<()> {
c83013a1 237 for out in dst.chunks_mut(2) {
aab478c1 238 let val = br.read_cb(cb)? as usize;
c83013a1
KS
239 out[0] = ATRAC3_MODE1_CB[val * 2 + 0] * scale;
240 out[1] = ATRAC3_MODE1_CB[val * 2 + 1] * scale;
aab478c1
KS
241 }
242 Ok(())
243}
244
245fn read_coeffs_other(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], scale: f32) -> DecoderResult<()> {
c83013a1 246 for el in dst.iter_mut() {
aab478c1
KS
247 let val = (br.read_cb(cb)? as i8) + 1;
248 let sign = (val & 1) != 0;
c83013a1
KS
249 let coef = f32::from(if sign { -(val >> 1) } else { val >> 1 });
250 *el = coef * scale;
aab478c1
KS
251 }
252 Ok(())
253}
254
255struct DSP {
256 imdct: IMDCT,
257 window: [f32; 512],
258 gain_tab: [f32; 16],
259 gain_tab2: [f32; 32],
260 tmp: [f32; ATRAC3_FRAME_SIZE + 64],
261}
262
61cab15b 263#[allow(clippy::manual_memcpy)]
aab478c1
KS
264impl DSP {
265 fn new() -> Self {
266 let mut gain_tab: [f32; 16] = [0.0; 16];
267 let mut gain_tab2: [f32; 32] = [0.0; 32];
268
269 for i in 0..16 {
270 gain_tab[i] = 2.0f32.powf(4.0 - (i as f32));
271 }
272 for i in 0..32 {
273 gain_tab2[i] = 2.0f32.powf(((i as f32) - 15.0) * -0.125);
274 }
275
276 let mut tmpw: [f32; 256] = [0.0; 256];
277 for i in 0..tmpw.len() {
278 tmpw[i] = (((((i as f32) + 0.5) / 256.0 - 0.5) * consts::PI).sin() + 1.0) * 0.5;
279 }
280
281 let mut window: [f32; 512] = [0.0; 512];
282 for i in 0..tmpw.len() {
283 let w = tmpw[i] / (tmpw[i] * tmpw[i] + tmpw[255 - i] * tmpw[255 - i]);
284 window[i] = w;
285 window[512 - 1 - i] = w;
286 }
1a151e53 287
aab478c1 288 Self {
9e78289c 289 imdct: IMDCT::new(512, false),
aab478c1
KS
290 tmp: [0.0; ATRAC3_FRAME_SIZE + 64],
291 gain_tab, gain_tab2, window,
292 }
293 }
294 fn synth_band(&mut self, src: &[f32]) {
295 let dst = &mut self.tmp;
296 self.imdct.imdct(src, dst);
297 for i in 0..512 {
298 dst[i] *= self.window[i];
299 }
300 }
301 fn apply_gains(&mut self, dst: &mut [f32], delay: &[f32], gain_data: &mut [GainData; 2], block_no: usize, band: usize) {
302 let prev_ngains = gain_data[block_no ^ 1].ngains[band];
303 let gain1 = if gain_data[block_no].ngains[band] > 0 {
304 self.gain_tab[gain_data[block_no].gain_lev[band][0]]
305 } else { 1.0 };
306
307 if prev_ngains == 0 {
308 for i in 0..256 {
309 dst[i] = self.tmp[i] * gain1 + delay[i];
310 }
311 return;
312 }
313
314 gain_data[block_no ^ 1].gain_lev[band][prev_ngains] = 4;
315 gain_data[block_no ^ 1].gain_loc[band][prev_ngains] = 32;
316
317 let mut off = 0;
318 for i in 0..prev_ngains {
319 let start = gain_data[block_no ^ 1].gain_loc[band][i] * 8;
320 let end = start + 8;
321
322 let mut gain2 = self.gain_tab [gain_data[block_no ^ 1].gain_lev[band][i]];
323 let gain_inc = self.gain_tab2[gain_data[block_no ^ 1].gain_lev[band][i + 1] + 15 -
324 gain_data[block_no ^ 1].gain_lev[band][i]];
325
326 while off < start {
327 dst[off] = (self.tmp[off] * gain1 + delay[off]) * gain2;
328 off += 1;
329 }
330 while off < end {
331 dst[off] = (self.tmp[off] * gain1 + delay[off]) * gain2;
332 gain2 *= gain_inc;
333 off += 1;
334 }
335 }
336 for i in off..256 {
337 dst[i] = self.tmp[i] * gain1 + delay[i];
338 }
339 }
340 fn qmf_prepare(&mut self, src: &[f32], delay: &[f32], size: usize, swap: bool) {
341 for i in 0..46 {
342 self.tmp[i] = delay[i];
343 }
344 let (s0, s1) = if !swap {
345 (&src[0..], &src[size/2..])
346 } else {
347 (&src[size/2..], &src[0..])
348 };
349 for i in (0..size).step_by(4) {
350 self.tmp[46 + i + 0] = s0[i / 2 + 0] + s1[i / 2 + 0];
351 self.tmp[46 + i + 1] = s0[i / 2 + 0] - s1[i / 2 + 0];
352 self.tmp[46 + i + 2] = s0[i / 2 + 1] + s1[i / 2 + 1];
353 self.tmp[46 + i + 3] = s0[i / 2 + 1] - s1[i / 2 + 1];
354 }
355 }
356 fn qmf_synth(&mut self, dst: &mut [f32], size: usize) {
357 for i in (0..size).step_by(2) {
358 let mut acc0 = 0.0;
359 let mut acc1 = 0.0;
360
361 for j in (0..ATRAC3_QMF_FILTER.len()).step_by(2) {
362 acc0 += self.tmp[i + j + 0] * ATRAC3_QMF_FILTER[j + 0];
363 acc1 += self.tmp[i + j + 1] * ATRAC3_QMF_FILTER[j + 1];
364 }
365 dst[i + 0] = acc1 * consts::SQRT_2 / 256.0;
366 dst[i + 1] = acc0 * consts::SQRT_2 / 256.0;
367 }
368 }
369 fn do_qmf(&mut self, dst: &mut [f32], delay: &mut [f32], swap: bool) {
370 self.qmf_prepare(dst, delay, 512, swap);
371 self.qmf_synth(dst, 512);
372 for i in 0..46 {
373 delay[i] = self.tmp[512 + i];
374 }
375 }
376 fn do_qmf_out(&mut self, dst: &mut [f32], src: &[f32], delay: &mut [f32]) {
377 self.qmf_prepare(src, delay, 1024, false);
378 self.qmf_synth(dst, 1024);
379 for i in 0..46 {
380 delay[i] = self.tmp[1024 + i];
381 }
382 }
383}
384
385struct Atrac3Decoder {
2422d969 386 info: NACodecInfoRef,
aab478c1
KS
387 channels: usize,
388 chmap: NAChannelMap,
389 samples: usize,
390 mode: Mode,
391 scrambled: bool,
392
393 codebooks: [Codebook<u8>; 7],
394 dsp: DSP,
395 ch_data: [Channel; 2],
396 scalefactors: [f32; 64],
397
398 mci_prev: [usize; 4],
399 mci_cur: [usize; 4],
400 mci_next: [usize; 4],
401
402 weighting_delay: [u8; 6],
403
404 pkt_buf: Vec<u8>,
405}
406
407struct Atrac3CodebookReader {
408 bits: &'static [u8],
409 codes: &'static [u8],
410}
411impl CodebookDescReader<u8> for Atrac3CodebookReader {
412 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
61cab15b 413 fn code(&mut self, idx: usize) -> u32 { u32::from(self.codes[idx]) }
aab478c1
KS
414 fn sym (&mut self, idx: usize) -> u8 { idx as u8 }
415 fn len(&mut self) -> usize { self.bits.len() }
416}
417
418impl Atrac3Decoder {
419 fn new() -> Self {
420 let mut scalefactors: [f32; 64] = [0.0; 64];
421 for i in 0..scalefactors.len() {
422 scalefactors[i] = 2.0f32.powf(((i as f32) - 15.0) / 3.0);
423 }
424
425 let mut cb0 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[0], bits: ATRAC3_HUFF_BITS[0] };
426 let mut cb1 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[1], bits: ATRAC3_HUFF_BITS[1] };
427 let mut cb2 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[2], bits: ATRAC3_HUFF_BITS[2] };
428 let mut cb3 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[3], bits: ATRAC3_HUFF_BITS[3] };
429 let mut cb4 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[4], bits: ATRAC3_HUFF_BITS[4] };
430 let mut cb5 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[5], bits: ATRAC3_HUFF_BITS[5] };
431 let mut cb6 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[6], bits: ATRAC3_HUFF_BITS[6] };
432 Self {
433 info: NACodecInfo::new_dummy(),
434 chmap: NAChannelMap::new(),
435 channels: 0,
436 samples: 0,
437 mode: Mode::Mono,
438 scrambled: false,
439
440 dsp: DSP::new(),
441 ch_data: [Channel::new(), Channel::new()],
442 codebooks: [Codebook::new(&mut cb0, CodebookMode::MSB).unwrap(),
443 Codebook::new(&mut cb1, CodebookMode::MSB).unwrap(),
444 Codebook::new(&mut cb2, CodebookMode::MSB).unwrap(),
445 Codebook::new(&mut cb3, CodebookMode::MSB).unwrap(),
446 Codebook::new(&mut cb4, CodebookMode::MSB).unwrap(),
447 Codebook::new(&mut cb5, CodebookMode::MSB).unwrap(),
448 Codebook::new(&mut cb6, CodebookMode::MSB).unwrap() ],
449
450 mci_prev: [3; 4],
451 mci_cur: [3; 4],
452 mci_next: [3; 4],
453
454 weighting_delay: ATRAC3_WEIGHTING_DELAYS,
455 pkt_buf: Vec::with_capacity(65536),
456 scalefactors,
457 }
458 }
61cab15b 459 #[allow(clippy::identity_op)]
aab478c1
KS
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 {
c83013a1 515 let w = f32::from(self.weighting_delay[1]) / 7.0;
aab478c1
KS
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 {
c83013a1 527 let w = f32::from(self.weighting_delay[3]) / 7.0;
aab478c1
KS
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 {
fa90ccfb 627 let mut br = BitReader::new(&self.pkt_buf[0..frame_size], BitReaderMode::BE);
aab478c1
KS
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 }
fa90ccfb 649 let mut br = BitReader::new(&self.pkt_buf[off..frame_size], BitReaderMode::BE);
aab478c1
KS
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 691 }
f9be4e75
KS
692 fn flush(&mut self) {
693 for ch_data in self.ch_data.iter_mut() {
694 ch_data.delay = [0.0; 1024];
695 ch_data.qmf_delay = [0.0; 64 * 3];
696 }
697 }
aab478c1
KS
698}
699
7d57ae2f
KS
700impl NAOptionHandler for Atrac3Decoder {
701 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
702 fn set_options(&mut self, _options: &[NAOption]) { }
703 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
704}
705
08a1fab7 706pub fn get_decoder() -> Box<dyn NADecoder + Send> {
aab478c1
KS
707 Box::new(Atrac3Decoder::new())
708}
709
710#[cfg(test)]
711mod test {
4f6124ac
KS
712 use nihav_core::codecs::RegisteredDecoders;
713 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 714 use nihav_codec_support::test::dec_video::test_decode_audio;
78fb6560 715 use crate::generic_register_all_decoders;
e64739f8 716 use nihav_realmedia::realmedia_register_all_demuxers;
aab478c1
KS
717 #[test]
718 fn test_atrac3() {
4f6124ac
KS
719 let mut dmx_reg = RegisteredDemuxers::new();
720 realmedia_register_all_demuxers(&mut dmx_reg);
721 let mut dec_reg = RegisteredDecoders::new();
78fb6560 722 generic_register_all_decoders(&mut dec_reg);
4f6124ac 723
886cde48 724 // samples from private collection
aab478c1
KS
725 let file = "assets/RV/rv30_atrc_384x208_realproducer_plus_8.51.rm";
726// let file = "assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm";
5580b11b 727 test_decode_audio("realmedia", file, Some(12000), None/*Some("atrac3")*/, &dmx_reg, &dec_reg);
aab478c1
KS
728 }
729}
730
731const ATRAC3_XOR_KEY: [u8; 4] = [ 0x53, 0x7F, 0x61, 0x03 ];
732
733const ATRAC3_HUFF_CODES: [&[u8]; 7] = [
734 &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x1C, 0x1D, 0x1E, 0x1F ],
735 &[ 0x00, 0x04, 0x05, 0x06, 0x07 ],
736 &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F ],
737 &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x1C, 0x1D, 0x1E, 0x1F ], // same as 0
738 &[ 0x00, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x1C, 0x1D, 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x0D ],
739 &[ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x14,
740 0x15, 0x16, 0x17, 0x18, 0x19, 0x34, 0x35, 0x36,
741 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x78, 0x79, 0x7A,
742 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x08, 0x09 ],
743 &[ 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
744 0x0F, 0x10, 0x11, 0x24, 0x25, 0x26, 0x27, 0x28,
745 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
746 0x31, 0x32, 0x33, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
747 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
748 0x75, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2,
749 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
750 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x02, 0x03 ]
751];
752const ATRAC3_HUFF_BITS: [&[u8]; 7] = [
753 &[ 1, 3, 3, 4, 4, 5, 5, 5, 5 ],
754 &[ 1, 3, 3, 3, 3 ],
755 &[ 1, 3, 3, 4, 4, 4, 4 ],
756 &[ 1, 3, 3, 4, 4, 5, 5, 5, 5 ],
757 &[ 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 4, 4 ],
758 &[ 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 ],
759 &[ 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,
760 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 ],
761];
762
763const 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 ];
764
765const ATRAC3_SUBBANDS: [usize; 32 + 1] = [
766 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176,
767 192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896,
768 1024
769];
770
771const ATRAC3_MATRIX_COEFFS: [f32; 8] = [ 0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0 ];
772
773const ATRAC3_QMF_FILTER: [f32; 48] = [
774 -0.000029238139, -0.000184109580, -0.000112315138, 0.000602345390,
775 0.000484503806, -0.001705877949, -0.001041114796, 0.004068033770,
776 0.001566677820, -0.008430772461, -0.001512299757, 0.015680588782,
777 -0.000122339843, -0.026883240789, 0.004925364163, 0.043472178280,
778 -0.015603342094, -0.068180441856, 0.037618979812, 0.108652018011,
779 -0.087192758918, -0.198768734932, 0.264158189297, 0.928483188152,
780 0.928483188152, 0.264158189297, -0.198768734932, -0.087192758918,
781 0.108652018011, 0.037618979812, -0.068180441856, -0.015603342094,
782 0.043472178280, 0.004925364163, -0.026883240789, -0.000122339843,
783 0.015680588782, -0.001512299757, -0.008430772461, 0.001566677820,
784 0.004068033770, -0.001041114796, -0.001705877949, 0.000484503806,
785 0.000602345390, -0.000112315138, -0.000184109580, -0.000029238139
786];