1#[allow(unused_imports)]
16use imdct;
17use std::error;
18use std::fmt;
19use std::cmp::min;
20use std::iter;
21use tinyvec::TinyVec;
22use ::ilog;
23use ::bitpacking::BitpackCursor;
24use ::header::{Codebook, Floor, FloorTypeZero, FloorTypeOne,
25 HuffmanVqReadErr, IdentHeader, Mapping, Residue, SetupHeader};
26use samples::Samples;
27
28#[derive(Debug, PartialEq, Eq)]
29pub enum AudioReadError {
30 EndOfPacket,
31 AudioBadFormat,
32 AudioIsHeader,
33 BufferNotAddressable,
43}
44
45impl From<()> for AudioReadError {
49 fn from(_ :()) -> AudioReadError {
50 AudioReadError::EndOfPacket
51 }
52}
53
54impl error::Error for AudioReadError {}
55
56impl fmt::Display for AudioReadError {
57 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
58 let description = match self {
59 AudioReadError::EndOfPacket => "End of packet reached.",
60 AudioReadError::AudioBadFormat => "Invalid audio packet",
61 AudioReadError::AudioIsHeader => "The vorbis version is not supported",
62 AudioReadError::BufferNotAddressable => "Requested to create buffer of non-addressable size",
63 };
64 write!(fmt, "{}", description)
65 }
66}
67
68enum DecodedFloor<'a> {
69 TypeZero(Vec<f32>, u64, &'a FloorTypeZero),
70 TypeOne(Vec<u32>, &'a FloorTypeOne),
71 Unused,
72}
73
74impl <'a> DecodedFloor<'a> {
75 fn is_unused(&self) -> bool {
76 match self {
77 &DecodedFloor::Unused => true,
78 _ => false,
79 }
80 }
81}
82
83enum FloorSpecialCase {
84 Unused,
85 PacketUndecodable,
86}
87
88impl From<()> for FloorSpecialCase {
89 fn from(_ :()) -> Self {
90 return FloorSpecialCase::Unused;
93 }
94}
95
96impl From<HuffmanVqReadErr> for FloorSpecialCase {
97 fn from(e :HuffmanVqReadErr) -> Self {
98 use ::header::HuffmanVqReadErr::*;
99 use self::FloorSpecialCase::*;
100 match e {
101 EndOfPacket => Unused,
102 NoVqLookupForCodebook => PacketUndecodable,
105 }
106 }
107}
108
109fn floor_zero_decode(rdr :&mut BitpackCursor, codebooks :&[Codebook],
112 fl :&FloorTypeZero) -> Result<(Vec<f32>, u64), FloorSpecialCase> {
113 let amplitude = try!(rdr.read_dyn_u64(fl.floor0_amplitude_bits));
116 if amplitude <= 0 {
117 return Err(FloorSpecialCase::Unused);
120 }
121
122 let booknumber = try!(rdr.read_dyn_u32(
123 ::ilog(fl.floor0_number_of_books as u64)));
124 match fl.floor0_book_list.get(booknumber as usize) {
125 None => try!(Err(FloorSpecialCase::PacketUndecodable)),
127 Some(codebook_idx) => {
128 let mut coefficients = Vec::with_capacity(fl.floor0_order as usize);
129 let mut last = 0.0;
130 let codebook = &codebooks[*codebook_idx as usize];
131 loop {
132 let mut last_new = last;
133 let temp_vector = try!(rdr.read_huffman_vq(codebook));
134 if temp_vector.len() + coefficients.len() < fl.floor0_order as usize {
135 for &e in temp_vector {
137 coefficients.push((last + e as f32).cos());
138 last_new = e as f32;
139 }
140 } else {
141 for &e in temp_vector {
142 coefficients.push((last + e as f32).cos());
143 last_new = e as f32;
144 if coefficients.len() == fl.floor0_order as usize {
148 return Ok((coefficients, amplitude));
149 }
150 }
151 }
152 last += last_new;
153 if coefficients.len() >= fl.floor0_order as usize {
154 return Ok((coefficients, amplitude));
155 }
156 }
157 },
158 }
159 unreachable!();
160}
161
162fn floor_zero_compute_curve(cos_coefficients :&[f32], amplitude :u64,
163 fl :&FloorTypeZero, blockflag :bool, n :u16) -> Vec<f32> {
164 let cached_bark_cos_omega =
165 &fl.cached_bark_cos_omega[blockflag as usize];
166 let mut i = 0;
167 let mut output = Vec::with_capacity(n as usize);
168 let lfv_common_term = amplitude as f32 * fl.floor0_amplitude_offset as f32 /
169 ((1 << fl.floor0_amplitude_bits) - 1) as f32;
170 while i < n as usize {
171 let cos_omega = cached_bark_cos_omega[i];
172
173 let (p_upper_border, q_upper_border) =
175 if fl.floor0_order & 1 == 1 {
176 ((fl.floor0_order as usize - 3) / 2,
177 (fl.floor0_order as usize - 1) / 2)
178 } else {
179 let v = (fl.floor0_order as usize - 2) / 2;
180 (v, v)
181 };
182 let (mut p, mut q) =
183 if fl.floor0_order & 1 == 1 {
184 (1.0 - cos_omega * cos_omega, 0.25)
185 } else {
186 ((1.0 - cos_omega) / 2.0, (1.0 + cos_omega) / 2.0)
187 };
188 for j in 0 .. p_upper_border + 1 {
189 let pm = cos_coefficients[2 * j + 1] - cos_omega;
190 p *= 4.0 * pm * pm;
191 }
192 for j in 0 .. q_upper_border + 1 {
193 let qm = cos_coefficients[2 * j] - cos_omega;
194 q *= 4.0 * qm * qm;
195 }
196
197 let linear_floor_value = (0.11512925 *
199 (lfv_common_term / (p+q).sqrt() - fl.floor0_amplitude_offset as f32)
200 ).exp();
201
202 let mut iteration_condition = cos_omega;
204 while cos_omega == iteration_condition {
205 output.push(linear_floor_value);
206 i += 1;
207 iteration_condition = match cached_bark_cos_omega.get(i) {
208 Some(v) => *v,
209 None => break,
210 };
211 }
212 }
213 return output;
214}
215
216fn floor_one_decode(rdr :&mut BitpackCursor, codebooks :&[Codebook],
218 fl :&FloorTypeOne) -> Result<Vec<u32>, FloorSpecialCase> {
219 if !try!(rdr.read_bit_flag()) {
222 try!(Err(()));
223 }
224 let mut floor1_y = Vec::new();
225 let v = &[256, 128, 86, 64];
226 let range = v[(fl.floor1_multiplier - 1) as usize];
227 let b = ::ilog(range - 1);
228 floor1_y.push(try!(rdr.read_dyn_u8(b)) as u32);
229 floor1_y.push(try!(rdr.read_dyn_u8(b)) as u32);
230
231 for class in &fl.floor1_partition_class {
232 let uclass = *class as usize;
233 let cdim = fl.floor1_class_dimensions[uclass];
234 let cbits = fl.floor1_class_subclasses[uclass];
235 let csub = (1 << cbits) - 1;
236 let mut cval = 0;
237 if cbits > 0 {
238 let cbook = fl.floor1_class_masterbooks[uclass] as usize;
239 cval = try!(rdr.read_huffman(&codebooks[cbook].codebook_huffman_tree));
240 }
241 for _ in 0 .. cdim {
242 let book = fl.floor1_subclass_books[uclass][(cval & csub) as usize];
243 cval >>= cbits;
244 if book >= 0 {
245 let tree = &codebooks[book as usize].codebook_huffman_tree;
246 floor1_y.push(try!(rdr.read_huffman(tree)));
247 } else {
248 floor1_y.push(0);
249 }
250 }
251 }
252 return Ok(floor1_y);
253}
254
255fn extr_neighbor<F>(v :&[u32], max_idx :usize,
256 compare :F, relation :&str) -> (usize, u32)
257 where F :Fn(u32, u32) -> std::cmp::Ordering {
258 use std::cmp::Ordering;
259
260 let bound = v[max_idx];
261 let prefix = &v[..max_idx];
262 let smaller = |a, b| compare(a, b) == Ordering::Less;
263
264 let min_idx = prefix.iter()
267 .position(|&val| smaller(val, bound))
268 .unwrap_or_else(||
269 panic!("No index y < {0} found where v[y] is {1} than v[{0}] = 0x{2:08x}!",
270 max_idx, relation, bound));
271
272 let (offset, max_neighbor) = prefix[min_idx..].iter().cloned()
274 .enumerate()
275 .rev()
280 .filter(|&(_i, val)| smaller(val, bound))
281 .max_by(|&(_, a), &(_, b)| compare(a, b))
282 .unwrap_or((0, v[min_idx]));
283
284 (min_idx + offset, max_neighbor)
285}
286
287fn low_neighbor(v :&[u32], x :usize) -> (usize, u32) {
288 extr_neighbor(v, x, |a, b| a.cmp(&b), "smaller")
289}
290
291
292fn high_neighbor(v :&[u32], x :usize) -> (usize, u32) {
293 extr_neighbor(v, x, |a, b| b.cmp(&a), "bigger")
294}
295
296#[test]
297fn test_low_neighbor() {
298 let v = [1, 4, 2, 3, 6, 5];
299 assert_eq!(low_neighbor(&v, 1), (0, 1));
301 assert_eq!(low_neighbor(&v, 2), (0, 1));
302 assert_eq!(low_neighbor(&v, 3), (2, 2));
303 assert_eq!(low_neighbor(&v, 4), (1, 4));
304 assert_eq!(low_neighbor(&v, 5), (1, 4));
305}
306
307
308#[test]
309fn test_high_neighbor() {
310 let v = [1, 4, 2, 3, 6, 5];
311 assert_eq!(high_neighbor(&v, 2), (1, 4));
313 assert_eq!(high_neighbor(&v, 3), (1, 4));
314 assert_eq!(high_neighbor(&v, 5), (4, 6));
316}
317
318#[test]
319fn test_high_neighbor_ex() {
320 let v = [0, 128, 12, 46, 4, 8, 16, 23,
322 33, 70, 2, 6, 10, 14, 19, 28, 39, 58, 90];
323
324 assert_eq!(high_neighbor(&v, 2), (1, 128));
326 assert_eq!(high_neighbor(&v, 3), (1, 128));
327 assert_eq!(high_neighbor(&v, 4), (2, 12));
328 assert_eq!(high_neighbor(&v, 5), (2, 12));
329 assert_eq!(high_neighbor(&v, 6), (3, 46));
330 assert_eq!(high_neighbor(&v, 7), (3, 46));
331 assert_eq!(high_neighbor(&v, 8), (3, 46));
332 assert_eq!(high_neighbor(&v, 9), (1, 128));
333 assert_eq!(high_neighbor(&v, 10), (4, 4));
334 assert_eq!(high_neighbor(&v, 11), (5, 8));
335 assert_eq!(high_neighbor(&v, 12), (2, 12));
336 assert_eq!(high_neighbor(&v, 13), (6, 16));
337 assert_eq!(high_neighbor(&v, 14), (7, 23));
338 assert_eq!(high_neighbor(&v, 15), (8, 33));
339 assert_eq!(high_neighbor(&v, 16), (3, 46));
340 assert_eq!(high_neighbor(&v, 17), (9, 70));
341 assert_eq!(high_neighbor(&v, 18), (1, 128));
342}
343
344#[test]
345#[should_panic]
346fn test_high_neighbor_panic() {
347 high_neighbor(&[1, 4, 3, 2, 6, 5], 4);
348}
349
350#[test]
351#[should_panic]
352fn test_low_neighbor_panic() {
353 low_neighbor(&[2, 4, 3, 1, 6, 5], 3);
354}
355
356fn render_point(x0 :u32, y0 :u32, x1 :u32, y1 :u32, x :u32) -> u32 {
357 let dy = y1 as i32 - y0 as i32;
360 let adx = x1 - x0;
361 let ady = dy.abs() as u32;
362 let err = ady * (x - x0);
363 let off = err / adx;
364 if dy < 0 {
365 return y0 - off;
366 } else {
367 return y0 + off;
368 }
369}
370
371#[test]
372fn test_render_point() {
373 assert_eq!(render_point(0, 28, 128, 67, 12), 31);
375 assert_eq!(render_point(12, 38, 128, 67, 46), 46);
376 assert_eq!(render_point(0, 28, 12, 38, 4), 31);
377 assert_eq!(render_point(4, 33, 12, 38, 8), 35);
378 assert_eq!(render_point(12, 38, 46, 31, 16), 38);
379 assert_eq!(render_point(16, 30, 46, 31, 23), 30);
380 assert_eq!(render_point(23, 40, 46, 31, 33), 37);
381 assert_eq!(render_point(46, 31, 128, 67, 70), 41);
382 assert_eq!(render_point(0, 28, 4, 33, 2), 30);
383 assert_eq!(render_point(4, 33, 8, 43, 6), 38);
384 assert_eq!(render_point(8, 43, 12, 38, 10), 41);
385 assert_eq!(render_point(12, 38, 16, 30, 14), 34);
386 assert_eq!(render_point(16, 30, 23, 40, 19), 34);
387 assert_eq!(render_point(23, 40, 33, 26, 28), 33);
388 assert_eq!(render_point(33, 26, 46, 31, 39), 28);
389 assert_eq!(render_point(46, 31, 70, 20, 58), 26);
390 assert_eq!(render_point(70, 20, 128, 67, 90), 36);
391}
392
393fn floor_one_curve_compute_amplitude(floor1_y :&[u32], fl :&FloorTypeOne) -> (Vec<u32>, Vec<bool>) {
394 let v = &[256, 128, 86, 64];
395 let range = v[(fl.floor1_multiplier - 1) as usize] as i32;
396 let mut floor1_step2_flag = Vec::new();
397 floor1_step2_flag.push(true);
398 floor1_step2_flag.push(true);
399 let mut floor1_final_y = Vec::new();
400 floor1_final_y.push(floor1_y[0]);
401 floor1_final_y.push(floor1_y[1]);
402
403 for (i, el) in fl.floor1_x_list.iter().enumerate().skip(2) {
404 let cur_low_neighbor = low_neighbor(&fl.floor1_x_list, i);
405 let cur_high_neighbor = high_neighbor(&fl.floor1_x_list, i);
406 let predicted = render_point(
407 cur_low_neighbor.1, floor1_final_y[cur_low_neighbor.0],
408 cur_high_neighbor.1, floor1_final_y[cur_high_neighbor.0], *el) as i32;
409 let val = floor1_y[i] as i32;
410 let highroom = range - predicted;
411 let lowroom = predicted;
412 let room = min(highroom, lowroom) * 2;
413 if val > 0 {
414 floor1_step2_flag[cur_low_neighbor.0] = true;
415 floor1_step2_flag[cur_high_neighbor.0] = true;
416 floor1_step2_flag.push(true);
417 floor1_final_y.push(if val >= room {
418 if highroom > lowroom {
419 predicted + val - lowroom
420 } else {
421 predicted - val + highroom - 1
422 }
423 } else {
424 predicted + (if val % 2 == 1 {
425 - val - 1 } else { val } >> 1)
426 } as u32);
427 } else {
428 floor1_final_y.push(predicted as u32);
429 floor1_step2_flag.push(false);
430 }
431 }
432 for el in &mut floor1_final_y {
434 *el = min(range as u32 - 1, *el);
435 }
436 return (floor1_final_y, floor1_step2_flag);
437}
438
439static FLOOR1_INVERSE_DB_TABLE :&[f32] = &[
440 1.0649863e-07, 1.1341951e-07, 1.2079015e-07, 1.2863978e-07,
441 1.3699951e-07, 1.4590251e-07, 1.5538408e-07, 1.6548181e-07,
442 1.7623575e-07, 1.8768855e-07, 1.9988561e-07, 2.1287530e-07,
443 2.2670913e-07, 2.4144197e-07, 2.5713223e-07, 2.7384213e-07,
444 2.9163793e-07, 3.1059021e-07, 3.3077411e-07, 3.5226968e-07,
445 3.7516214e-07, 3.9954229e-07, 4.2550680e-07, 4.5315863e-07,
446 4.8260743e-07, 5.1396998e-07, 5.4737065e-07, 5.8294187e-07,
447 6.2082472e-07, 6.6116941e-07, 7.0413592e-07, 7.4989464e-07,
448 7.9862701e-07, 8.5052630e-07, 9.0579828e-07, 9.6466216e-07,
449 1.0273513e-06, 1.0941144e-06, 1.1652161e-06, 1.2409384e-06,
450 1.3215816e-06, 1.4074654e-06, 1.4989305e-06, 1.5963394e-06,
451 1.7000785e-06, 1.8105592e-06, 1.9282195e-06, 2.0535261e-06,
452 2.1869758e-06, 2.3290978e-06, 2.4804557e-06, 2.6416497e-06,
453 2.8133190e-06, 2.9961443e-06, 3.1908506e-06, 3.3982101e-06,
454 3.6190449e-06, 3.8542308e-06, 4.1047004e-06, 4.3714470e-06,
455 4.6555282e-06, 4.9580707e-06, 5.2802740e-06, 5.6234160e-06,
456 5.9888572e-06, 6.3780469e-06, 6.7925283e-06, 7.2339451e-06,
457 7.7040476e-06, 8.2047000e-06, 8.7378876e-06, 9.3057248e-06,
458 9.9104632e-06, 1.0554501e-05, 1.1240392e-05, 1.1970856e-05,
459 1.2748789e-05, 1.3577278e-05, 1.4459606e-05, 1.5399272e-05,
460 1.6400004e-05, 1.7465768e-05, 1.8600792e-05, 1.9809576e-05,
461 2.1096914e-05, 2.2467911e-05, 2.3928002e-05, 2.5482978e-05,
462 2.7139006e-05, 2.8902651e-05, 3.0780908e-05, 3.2781225e-05,
463 3.4911534e-05, 3.7180282e-05, 3.9596466e-05, 4.2169667e-05,
464 4.4910090e-05, 4.7828601e-05, 5.0936773e-05, 5.4246931e-05,
465 5.7772202e-05, 6.1526565e-05, 6.5524908e-05, 6.9783085e-05,
466 7.4317983e-05, 7.9147585e-05, 8.4291040e-05, 8.9768747e-05,
467 9.5602426e-05, 0.00010181521, 0.00010843174, 0.00011547824,
468 0.00012298267, 0.00013097477, 0.00013948625, 0.00014855085,
469 0.00015820453, 0.00016848555, 0.00017943469, 0.00019109536,
470 0.00020351382, 0.00021673929, 0.00023082423, 0.00024582449,
471 0.00026179955, 0.00027881276, 0.00029693158, 0.00031622787,
472 0.00033677814, 0.00035866388, 0.00038197188, 0.00040679456,
473 0.00043323036, 0.00046138411, 0.00049136745, 0.00052329927,
474 0.00055730621, 0.00059352311, 0.00063209358, 0.00067317058,
475 0.00071691700, 0.00076350630, 0.00081312324, 0.00086596457,
476 0.00092223983, 0.00098217216, 0.0010459992, 0.0011139742,
477 0.0011863665, 0.0012634633, 0.0013455702, 0.0014330129,
478 0.0015261382, 0.0016253153, 0.0017309374, 0.0018434235,
479 0.0019632195, 0.0020908006, 0.0022266726, 0.0023713743,
480 0.0025254795, 0.0026895994, 0.0028643847, 0.0030505286,
481 0.0032487691, 0.0034598925, 0.0036847358, 0.0039241906,
482 0.0041792066, 0.0044507950, 0.0047400328, 0.0050480668,
483 0.0053761186, 0.0057254891, 0.0060975636, 0.0064938176,
484 0.0069158225, 0.0073652516, 0.0078438871, 0.0083536271,
485 0.0088964928, 0.009474637, 0.010090352, 0.010746080,
486 0.011444421, 0.012188144, 0.012980198, 0.013823725,
487 0.014722068, 0.015678791, 0.016697687, 0.017782797,
488 0.018938423, 0.020169149, 0.021479854, 0.022875735,
489 0.024362330, 0.025945531, 0.027631618, 0.029427276,
490 0.031339626, 0.033376252, 0.035545228, 0.037855157,
491 0.040315199, 0.042935108, 0.045725273, 0.048696758,
492 0.051861348, 0.055231591, 0.058820850, 0.062643361,
493 0.066714279, 0.071049749, 0.075666962, 0.080584227,
494 0.085821044, 0.091398179, 0.097337747, 0.10366330,
495 0.11039993, 0.11757434, 0.12521498, 0.13335215,
496 0.14201813, 0.15124727, 0.16107617, 0.17154380,
497 0.18269168, 0.19456402, 0.20720788, 0.22067342,
498 0.23501402, 0.25028656, 0.26655159, 0.28387361,
499 0.30232132, 0.32196786, 0.34289114, 0.36517414,
500 0.38890521, 0.41417847, 0.44109412, 0.46975890,
501 0.50028648, 0.53279791, 0.56742212, 0.60429640,
502 0.64356699, 0.68538959, 0.72993007, 0.77736504,
503 0.82788260, 0.88168307, 0.9389798, 1.];
504
505fn render_line(x0 :u32, y0 :u32, x1 :u32, y1 :u32, v :&mut Vec<u32>) {
506 let dy = y1 as i32 - y0 as i32;
508 let adx = x1 as i32 - x0 as i32;
509 let ady = dy.abs();
510 let base = dy / adx;
511 let mut y = y0 as i32;
512 let mut err = 0;
513 let sy = base + (if dy < 0 { -1 } else { 1 });
514 let ady = ady - base.abs() * adx;
515 v.push(y as u32);
516 for _ in (x0 + 1) .. x1 {
517 err += ady;
518 if err >= adx {
519 err -= adx;
520 y += sy;
521 } else {
522 y += base;
523 }
524 v.push(y as u32);
525 }
526}
527
528fn floor_one_curve_synthesis(floor1_final_y :Vec<u32>,
529 floor1_step2_flag :Vec<bool>, fl :&FloorTypeOne, n :u16) -> Vec<f32> {
530 let floor1_final_y_s = |i :usize| { floor1_final_y[fl.floor1_x_list_sorted[i].0] };
531 let floor1_x_list_s = |i :usize| { fl.floor1_x_list_sorted[i].1 };
532 let floor1_step2_flag_s = |i :usize| {
533 floor1_step2_flag[fl.floor1_x_list_sorted[i].0] };
534 let mut hx = 0;
535 let mut lx = 0;
536 let mut hy = 0;
537 let mut floor = Vec::with_capacity(n as usize);
538 let mut ly = floor1_final_y_s(0) * fl.floor1_multiplier as u32;
539 for i in 1 .. fl.floor1_x_list.len() {
540 if floor1_step2_flag_s(i) {
541 hy = floor1_final_y_s(i) * fl.floor1_multiplier as u32;
542 hx = floor1_x_list_s(i);
543 render_line(lx, ly, hx, hy, &mut floor);
544 lx = hx;
545 ly = hy;
546 }
547 }
548 if hx < n as u32 {
549 render_line(hx, hy, n as u32, hy, &mut floor);
550 } else if hx > n as u32 {
551 floor.truncate(n as usize);
552 }
553
554 floor.into_iter()
555 .map(|idx| FLOOR1_INVERSE_DB_TABLE[idx as usize])
556 .collect()
557}
558
559fn floor_decode<'a>(rdr :&mut BitpackCursor,
560 ident :&IdentHeader, mapping :&Mapping, codebooks :&[Codebook],
561 floors :&'a [Floor]) -> Result<Vec<DecodedFloor<'a>>, ()> {
562 let mut decoded_floor_infos = Vec::with_capacity(ident.audio_channels as usize);
563 for i in 0 .. ident.audio_channels as usize {
564 let submap_number = mapping.mapping_mux[i] as usize;
565 let floor_number = mapping.mapping_submap_floors[submap_number];
566 let floor = &floors[floor_number as usize];
567 use self::FloorSpecialCase::*;
568 let floor_res = match floor {
569 &Floor::TypeZero(ref fl) => {
570 match floor_zero_decode(rdr, codebooks, fl) {
571 Ok((coeff, amp)) => DecodedFloor::TypeZero(coeff, amp, fl),
572 Err(Unused) => DecodedFloor::Unused,
573 Err(PacketUndecodable) => try!(Err(())),
574 }
575 },
576 &Floor::TypeOne(ref fl) => {
577 match floor_one_decode(rdr, codebooks, fl) {
578 Ok(dfl) => DecodedFloor::TypeOne(dfl, fl),
579 Err(Unused) => DecodedFloor::Unused,
580 Err(PacketUndecodable) => try!(Err(())),
581 }
582 },
583 };
584 decoded_floor_infos.push(floor_res);
585 }
586 return Ok(decoded_floor_infos);
587}
588
589fn residue_packet_read_partition(rdr :&mut BitpackCursor, codebook :&Codebook,
590 resid :&Residue, vec_v :&mut [f32]) -> Result<(), HuffmanVqReadErr> {
591 if resid.residue_type == 0 {
592 let codebook_dimensions = codebook.codebook_dimensions as usize;
593 let step = resid.residue_partition_size as usize / codebook_dimensions;
594 for i in 0 .. step {
595 let entry_temp = try!(rdr.read_huffman_vq(codebook));
596 for (j, e) in entry_temp.iter().enumerate() {
597 vec_v[i + j * step] += *e;
598 }
599 }
600 } else {
601 let partition_size = resid.residue_partition_size as usize;
603 let mut i = 0;
604 while i < partition_size {
605 let entries = try!(rdr.read_huffman_vq(codebook));
606 let vs = if let Some(vs) = vec_v.get_mut(i..(i + entries.len())) {
607 vs
608 } else {
609 break;
610 };
611
612 for (v, e) in vs.iter_mut().zip(entries.iter()) {
613 *v += *e;
614 }
615
616 i += entries.len();
617 }
618 }
619 Ok(())
620}
621
622fn residue_packet_decode_inner(rdr :&mut BitpackCursor, cur_blocksize :u16,
623 do_not_decode_flag :&[bool], resid :&Residue, codebooks :&[Codebook]) -> Result<Vec<f32>, ()> {
624
625 let ch = do_not_decode_flag.len();
626 let actual_size = (cur_blocksize / 2) as usize;
627
628 let limit_residue_begin = min(resid.residue_begin as usize, actual_size);
633 let limit_residue_end = min(resid.residue_end as usize, actual_size);
634
635 let cur_codebook = &codebooks[resid.residue_classbook as usize];
636 let classwords_per_codeword = cur_codebook.codebook_dimensions as usize;
637 let n_to_read = limit_residue_end - limit_residue_begin;
638 let partitions_to_read = n_to_read / resid.residue_partition_size as usize;
639 let residue_classbok_ht = &cur_codebook.codebook_huffman_tree;
640
641 let mut vectors = vec![0.; ch * actual_size];
643
644 if n_to_read == 0 {
645 return Ok(vectors);
647 }
648
649 if classwords_per_codeword == 0 {
650 try!(Err(()));
653 }
654
655 'pseudo_return: loop {
656 macro_rules! eno {
658 ($expr:expr) => (match $expr {
659 $crate::std::result::Result::Ok(val) => val,
660 $crate::std::result::Result::Err(_) => break 'pseudo_return,
661 })
662 }
663 let cl_stride :usize = partitions_to_read + classwords_per_codeword;
664 let mut classifications = vec![0; ch as usize * cl_stride];
665 for pass in 0 .. 8 {
666 let mut partition_count = 0;
667 while partition_count < partitions_to_read {
668 if pass == 0 {
669 for (j, do_not_decode) in do_not_decode_flag.iter().enumerate() {
670 if *do_not_decode {
671 continue;
672 }
673 let mut temp = eno!(rdr.read_huffman(residue_classbok_ht));
674 for i in (0 .. classwords_per_codeword).rev() {
675 classifications[j * cl_stride + i + partition_count] =
676 temp % resid.residue_classifications as u32;
677 temp = temp / resid.residue_classifications as u32;
678 }
679 }
680 }
681 for _ in 0 .. classwords_per_codeword {
682 if partition_count >= partitions_to_read {
683 break;
684 }
685 for (j, do_not_decode) in do_not_decode_flag.iter().enumerate() {
686 if *do_not_decode {
687 continue;
688 }
689 let offs = limit_residue_begin + partition_count * resid.residue_partition_size as usize;
690 let vec_j_offs = &mut vectors[(j * actual_size + offs) .. ((j + 1) * actual_size)];
691 let vqclass = classifications[j * cl_stride + partition_count] as usize;
692 let vqbook_opt = resid.residue_books[vqclass].get_val(pass);
693 if let Some(vqbook) = vqbook_opt {
694 let codebook = &codebooks[vqbook as usize];
695 match residue_packet_read_partition(rdr,
698 codebook, resid, vec_j_offs) {
699 Ok(_) => (),
700 Err(err) => {
701 use ::header::HuffmanVqReadErr::*;
702 match err {
703 EndOfPacket => break 'pseudo_return,
704 NoVqLookupForCodebook =>
705 panic!("Codebook must have a value mapping"),
706 }
707 },
708 }
709 }
710 }
711 partition_count += 1;
712 }
713 }
714 }
715 break;
716 }
717
718 return Ok(vectors);
719}
720
721
722fn residue_packet_decode(rdr :&mut BitpackCursor, cur_blocksize :u16,
725 do_not_decode_flag :&[bool], resid :&Residue, codebooks :&[Codebook]) -> Result<Vec<f32>, ()> {
726
727 let ch = do_not_decode_flag.len();
728 let vec_size = (cur_blocksize / 2) as usize;
729
730 if resid.residue_type == 2 {
731 let mut to_decode_found = false;
732 for do_not_decode in do_not_decode_flag {
733 if !do_not_decode {
734 to_decode_found = true;
735 break;
736 }
737 }
738 if !to_decode_found {
739 return Ok(vec![0.; ch * vec_size]);
742 } else {
743 let c_do_not_decode_flag = [false];
745
746 let vectors = try!(residue_packet_decode_inner(rdr,
747 cur_blocksize * ch as u16, &c_do_not_decode_flag,
748 resid, codebooks));
749
750 let mut vectors_deinterleaved = Vec::with_capacity(ch * vec_size);
752 for j in 0 .. ch {
753 let iter = vectors.chunks(ch).map(|chunk| chunk[j]);
754 vectors_deinterleaved.extend(iter);
755 }
756 return Ok(vectors_deinterleaved);
757 }
758 } else {
759 return residue_packet_decode_inner(rdr, cur_blocksize,
760 do_not_decode_flag, resid, codebooks);
761 }
762}
763
764#[inline]
765fn inverse_couple(m :f32, a :f32) -> (f32, f32) {
766 if m > 0. {
767 if a > 0. {
768 (m, m - a)
769 } else {
770 (m + a, m)
771 }
772 } else {
773 if a > 0. {
774 (m, m + a)
775 } else {
776 (m - a, m)
777 }
778 }
779}
780
781fn dual_mut_idx<T>(v :&mut [T], idx_a :usize, idx_b :usize)
784 -> (&mut T, &mut T) {
785 assert_ne!(idx_a, idx_b, "not allowed, indices must be different!");
786
787 let range = if idx_a < idx_b { idx_a..idx_b+1 } else { idx_b..idx_a+1 };
788 let segment = &mut v[range];
789 let (first, rest) = segment.split_first_mut().unwrap();
790 let (last, _) = rest.split_last_mut().unwrap();
791 (first, last)
792}
793
794fn dct_iv_slow(buffer :&mut [f32]) {
795 let x = buffer.to_vec();
796 let n = buffer.len();
797 let nmask = (n << 3) - 1;
798 let mcos = (0 .. 8 * n)
799 .map(|i| (std::f32::consts::FRAC_PI_4 * (i as f32) / (n as f32)).cos())
800 .collect::<Vec<_>>();
801 for i in 0 .. n {
802 let mut acc = 0.;
803 for j in 0 .. n {
804 acc += x[j] * mcos[((2 * i + 1)*(2*j+1)) & nmask];
805 }
806 buffer[i] = acc;
807 }
808}
809
810#[allow(dead_code)]
811fn inverse_mdct_slow(buffer :&mut [f32]) {
812 let n = buffer.len();
813 let n4 = n >> 2;
814 let n2 = n >> 1;
815 let n3_4 = n - n4;
816 let mut temp = buffer[0 .. n2].to_vec();
817 dct_iv_slow(&mut temp); for i in 0 .. n4 {
819 buffer[i] = temp[i + n4]; }
821 for i in n4 .. n3_4 {
822 buffer[i] = -temp[n3_4 - i - 1]; }
824 for i in n3_4 .. n {
825 buffer[i] = -temp[i - n3_4]; }
827}
828
829#[cfg(test)]
830#[test]
831fn test_imdct_slow() {
832 use imdct_test::*;
833 let mut arr_1 = imdct_prepare(&IMDCT_INPUT_TEST_ARR_1);
834 inverse_mdct_slow(&mut arr_1);
835 let mismatches = fuzzy_compare_array(
836 &arr_1, &IMDCT_OUTPUT_TEST_ARR_1,
837 0.00005, true);
838 let mismatches_limit = 0;
839 if mismatches > mismatches_limit {
840 panic!("Numer of mismatches {} was larger than limit of {}",
841 mismatches, mismatches_limit);
842 }
843}
844
845pub struct PreviousWindowRight {
850 data :Option<Vec<Vec<f32>>>,
851}
852
853impl PreviousWindowRight {
854 pub fn new() -> Self {
856 return PreviousWindowRight{ data : None };
857 }
858 pub fn is_empty(&self) -> bool {
860 self.data.is_none()
861 }
862}
863
864pub fn get_decoded_sample_count(ident :&IdentHeader, setup :&SetupHeader, packet :&[u8])
876 -> Result<usize, AudioReadError> {
877 let mut rdr = BitpackCursor::new(packet);
878 if try!(rdr.read_bit_flag()) {
879 try!(Err(AudioReadError::AudioIsHeader));
880 }
881 let mode_number = try!(rdr.read_dyn_u8(ilog(setup.modes.len() as u64 - 1)));
882 let mode = &setup.modes[mode_number as usize];
883 let bs = if mode.mode_blockflag { ident.blocksize_1 } else { ident.blocksize_0 };
884 let n :u16 = 1 << bs;
885 let previous_next_window_flag = if mode.mode_blockflag {
886 Some((try!(rdr.read_bit_flag()), try!(rdr.read_bit_flag())))
887 } else {
888 None
889 };
890 let window_center = n >> 1;
892 let (left_win_start, _left_win_end, _left_n, _left_n_use_bs1) =
893 if previous_next_window_flag.map_or(true, |(prev_win_flag, _)| prev_win_flag) {
894 (0, window_center, n >> 1, mode.mode_blockflag)
895 } else {
896 let bs_0_exp = 1 << ident.blocksize_0;
897 ((n - bs_0_exp) >> 2, (n + bs_0_exp) >> 2, bs_0_exp >> 1, false)
898 };
899
900 let (right_win_start, _right_win_end) =
902 if previous_next_window_flag.map_or(true, |(_, next_win_flag)| next_win_flag) {
903 (window_center, n)
904 } else {
905 let bs_0_exp = 1 << ident.blocksize_0;
906 ((n * 3 - bs_0_exp) >> 2, (n * 3 + bs_0_exp) >> 2)
907 };
908
909 Ok((right_win_start - left_win_start) as usize)
910}
911
912#[allow(unused_variables)]
913pub fn read_audio_packet_generic<S :Samples>(ident :&IdentHeader, setup :&SetupHeader, packet :&[u8], pwr :&mut PreviousWindowRight)
922 -> Result<S, AudioReadError> {
923 let mut rdr = BitpackCursor::new(packet);
924 if try!(rdr.read_bit_flag()) {
925 try!(Err(AudioReadError::AudioIsHeader));
926 }
927 let mode_number = try!(rdr.read_dyn_u8(ilog(setup.modes.len() as u64 - 1)));
928 let mode = if let Some(mode) = setup.modes.get(mode_number as usize) {
929 mode
930 } else {
931 try!(Err(AudioReadError::AudioBadFormat))
932 };
933 let mapping = &setup.mappings[mode.mode_mapping as usize];
934 let bs = if mode.mode_blockflag { ident.blocksize_1 } else { ident.blocksize_0 };
935 let n :u16 = 1 << bs;
936 let previous_next_window_flag = if mode.mode_blockflag {
937 Some((try!(rdr.read_bit_flag()), try!(rdr.read_bit_flag())))
938 } else {
939 None
940 };
941 let decoded_floor_infos = try!(floor_decode(&mut rdr, ident, mapping,
943 &setup.codebooks, &setup.floors));
944
945 let mut no_residue = TinyVec::<[bool; 32]>::new();
947 for fl in &decoded_floor_infos {
948 no_residue.push(fl.is_unused());
949 }
950 for (&mag, &angle) in
952 mapping.mapping_magnitudes.iter().zip(mapping.mapping_angles.iter()) {
953 if ! (no_residue[mag as usize] && no_residue[angle as usize]) {
954 no_residue[mag as usize] = false;
955 no_residue[angle as usize] = false;
956 }
957 }
958
959 let mut residue_vectors = vec![vec![]; mapping.mapping_mux.len()];
961 let resid_vec_len = (n / 2) as usize;
963 for (i, &residue_number) in mapping.mapping_submap_residues.iter().enumerate() {
964 let mut do_not_decode_flag = TinyVec::<[bool; 32]>::new();
965 for (j, &mapping_mux_j) in mapping.mapping_mux.iter().enumerate() {
966 if mapping_mux_j as usize == i {
967 do_not_decode_flag.push(no_residue[j]);
968 }
969 }
970 let cur_residue = &setup.residues[residue_number as usize];
971 let vectors = match residue_packet_decode(&mut rdr, n,
972 &do_not_decode_flag, cur_residue, &setup.codebooks) {
973 Ok(v) => v,
974 Err(_) => return Err(AudioReadError::AudioBadFormat),
975 };
976 let mut ch = 0;
979 for (j, &mapping_mux_j) in mapping.mapping_mux.iter().enumerate() {
980 if mapping_mux_j as usize == i {
981 let vec_at_ch = &vectors[resid_vec_len * ch .. resid_vec_len * (ch + 1)];
983 residue_vectors[j].clear();
984 residue_vectors[j].extend_from_slice(vec_at_ch);
985 ch += 1;
986 }
987 }
988 }
989
990 record_residue_pre_inverse!(residue_vectors);
991
992 for (&mag, &angle) in
994 mapping.mapping_magnitudes.iter().rev().zip(mapping.mapping_angles.iter().rev()) {
995 let (mag_vector, angle_vector) = dual_mut_idx(&mut residue_vectors,
996 mag as usize, angle as usize);
997 for (m, a) in mag_vector.iter_mut().zip(angle_vector.iter_mut()) {
998 let (new_m, new_a) = inverse_couple(*m, *a);
1001 *m = new_m;
1002 *a = new_a;
1003 }
1004 }
1005
1006 record_residue_post_inverse!(residue_vectors);
1007
1008 let mut audio_spectri = Vec::with_capacity(ident.audio_channels as usize);
1010 for (residue_vector, chan_decoded_floor) in
1011 residue_vectors.iter().zip(decoded_floor_infos.iter()) {
1012 let mut floor_decoded :Vec<f32> = match chan_decoded_floor {
1013 &DecodedFloor::TypeZero(ref coefficients, amplitude, ref fl) => {
1014 floor_zero_compute_curve(coefficients, amplitude,
1015 fl, mode.mode_blockflag, n / 2)
1016 },
1017 &DecodedFloor::TypeOne(ref floor_y, ref fl) => {
1018 let (floor1_final_y, floor1_step2_flag) =
1019 floor_one_curve_compute_amplitude(floor_y, fl);
1020 floor_one_curve_synthesis(floor1_final_y,
1021 floor1_step2_flag, fl, n / 2)
1022 },
1023 &DecodedFloor::Unused => {
1024 vec![0.; (n / 2) as usize]
1026 },
1027 };
1028
1029 debug_assert_eq!(residue_vector.len(), (n / 2) as usize);
1034 debug_assert_eq!(floor_decoded.len(), (n / 2) as usize);
1035
1036 for (fl_sc, r_sc) in floor_decoded.iter_mut().zip(residue_vector.iter()) {
1038 *fl_sc *= *r_sc;
1039 }
1040 audio_spectri.push(floor_decoded);
1041 }
1042
1043 record_pre_mdct!(audio_spectri);
1044
1045 for ref mut spectrum in audio_spectri.iter_mut() {
1047 let size = (n / 2) as usize;
1048 let ext = iter::repeat(0.).take(size);
1049 spectrum.extend(ext);
1050 let cached_bd = &ident.cached_bs_derived[mode.mode_blockflag as usize];
1051 imdct::inverse_mdct(cached_bd, &mut spectrum[..], bs);
1053 }
1055
1056 record_post_mdct!(audio_spectri);
1057
1058 let window_center = n >> 1;
1060 let (left_win_start, left_win_end, left_n, left_n_use_bs1) =
1061 if previous_next_window_flag.map_or(true, |(prev_win_flag, _)| prev_win_flag) {
1062 (0, window_center, n >> 1, mode.mode_blockflag)
1063 } else {
1064 let bs_0_exp = 1 << ident.blocksize_0;
1065 ((n - bs_0_exp) >> 2, (n + bs_0_exp) >> 2, bs_0_exp >> 1, false)
1066 };
1067
1068 let (right_win_start, right_win_end) =
1070 if previous_next_window_flag.map_or(true, |(_, next_win_flag)| next_win_flag) {
1071 (window_center, n)
1072 } else {
1073 let bs_0_exp = 1 << ident.blocksize_0;
1074 ((n * 3 - bs_0_exp) >> 2, (n * 3 + bs_0_exp) >> 2)
1075 };
1076
1077 let mut future_prev_halves = Vec::with_capacity(ident.audio_channels as usize);
1085 if let Some(prev_data) = pwr.data.take() {
1086 assert_eq!(audio_spectri.len(), prev_data.len());
1089
1090 let win_slope = &ident.cached_bs_derived[left_n_use_bs1 as usize].window_slope;
1091
1092 for (prev_chan, chan) in prev_data.into_iter().zip(audio_spectri.iter_mut()) {
1093 let plen = prev_chan.len();
1094 let left_win_start = left_win_start as usize;
1095 let right_win_start = right_win_start as usize;
1096 let right_win_end = right_win_end as usize;
1097
1098 let range = {
1101 let start = left_win_start;
1102 let end = left_win_start + plen;
1103 start..end
1104 };
1105
1106 let prev = prev_chan[0..plen].iter();
1107
1108 let (lhs, rhs) = {
1109 if win_slope.len() < plen {
1110 try!(Err(AudioReadError::AudioBadFormat));
1113 }
1114 let win_slope = &win_slope[0..plen];
1115 (win_slope.iter(), win_slope.iter().rev())
1116 };
1117
1118 for (((v, lhs), prev), rhs) in chan[range].iter_mut().zip(lhs).zip(prev).zip(rhs) {
1119 *v = (*v * lhs) + (prev * rhs);
1120 }
1121
1122 let future_prev_half = chan[right_win_start..right_win_end].into();
1124
1125 future_prev_halves.push(future_prev_half);
1126
1127 if left_win_start > 0 {
1130 for i in 0 .. right_win_start - left_win_start {
1131 chan[i] = chan[i + left_win_start];
1132 }
1133 }
1134
1135 chan.truncate(right_win_start - left_win_start);
1138 }
1142 } else {
1143 for chan in audio_spectri.iter_mut() {
1144 let mut future_prev_half = Vec::with_capacity(
1145 (right_win_end - right_win_start) as usize);
1146 for i in right_win_start as usize .. right_win_end as usize {
1147 future_prev_half.push(chan[i]);
1148 }
1149 future_prev_halves.push(future_prev_half);
1150 chan.truncate(0);
1153 }
1154 }
1155
1156 pwr.data = Some(future_prev_halves);
1157
1158 let final_i16_samples = S::from_floats(audio_spectri);
1160
1161 Ok(final_i16_samples)
1162}
1163
1164pub fn read_audio_packet(ident :&IdentHeader, setup :&SetupHeader, packet :&[u8], pwr :&mut PreviousWindowRight)
1173 -> Result<Vec<Vec<i16>>, AudioReadError> {
1174 read_audio_packet_generic(ident, setup, packet, pwr)
1175}