1 // Vorbis decoder written in Rust
2 //
3 // Copyright (c) 2016 est31 <MTest31@outlook.com>
4 // and contributors. All rights reserved.
5 // Licensed under MIT license, or Apache 2 license,
6 // at your option. Please see the LICENSE file
7 // attached to this source distribution for details.
8
9 /*!
10 Audio packet decoding
11
12 This module decodes the audio packets given to it.
13 */
14
15 #[allow(unused_imports)]
16 use imdct;
17 use std::error;
18 use std::fmt;
19 use std::cmp::min;
20 use std::iter;
21 use tinyvec::TinyVec;
22 use ::ilog;
23 use ::bitpacking::BitpackCursor;
24 use ::header::{Codebook, Floor, FloorTypeZero, FloorTypeOne,
25 HuffmanVqReadErr, IdentHeader, Mapping, Residue, SetupHeader};
26 use samples::Samples;
27
28 #[derive(Debug, PartialEq, Eq)]
29 pub enum AudioReadError {
30 EndOfPacket,
31 AudioBadFormat,
32 AudioIsHeader,
33 /// If the needed memory isn't addressable by us
34 ///
35 /// This error is returned if a calculation yielded a higher value for
36 /// an internal buffer size that doesn't fit into the platform's address range.
37 /// Note that if we "simply" encounter an allocation failure (OOM, etc),
38 /// we do what libstd does in these cases: crash.
39 ///
40 /// This error is not automatically an error of the format,
41 /// but rather is due to insufficient decoder hardware.
42 BufferNotAddressable,
43 }
44
45 // For the () error type returned by the bitpacking layer
46 // TODO that type choice was a bit unfortunate,
47 // perhaps one day fix this
48 impl From<()> for AudioReadError {
from(_ :()) -> AudioReadError49 fn from(_ :()) -> AudioReadError {
50 AudioReadError::EndOfPacket
51 }
52 }
53
54 impl error::Error for AudioReadError {}
55
56 impl fmt::Display for AudioReadError {
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>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
68 enum DecodedFloor<'a> {
69 TypeZero(Vec<f32>, u64, &'a FloorTypeZero),
70 TypeOne(Vec<u32>, &'a FloorTypeOne),
71 Unused,
72 }
73
74 impl <'a> DecodedFloor<'a> {
is_unused(&self) -> bool75 fn is_unused(&self) -> bool {
76 match self {
77 &DecodedFloor::Unused => true,
78 _ => false,
79 }
80 }
81 }
82
83 enum FloorSpecialCase {
84 Unused,
85 PacketUndecodable,
86 }
87
88 impl From<()> for FloorSpecialCase {
from(_ :()) -> Self89 fn from(_ :()) -> Self {
90 // () always means end of packet condition in the places
91 // the conversion is used.
92 return FloorSpecialCase::Unused;
93 }
94 }
95
96 impl From<HuffmanVqReadErr> for FloorSpecialCase {
from(e :HuffmanVqReadErr) -> Self97 fn from(e :HuffmanVqReadErr) -> Self {
98 use ::header::HuffmanVqReadErr::*;
99 use self::FloorSpecialCase::*;
100 match e {
101 EndOfPacket => Unused,
102 // Undecodable per spec, see paragraph about
103 // VQ lookup type zero in section 3.3.
104 NoVqLookupForCodebook => PacketUndecodable,
105 }
106 }
107 }
108
109 // Note that the output vector contains the cosine values of the coefficients,
110 // not the bare values like in the spec. This is in order to optimize.
floor_zero_decode(rdr :&mut BitpackCursor, codebooks :&[Codebook], fl :&FloorTypeZero) -> Result<(Vec<f32>, u64), FloorSpecialCase>111 fn floor_zero_decode(rdr :&mut BitpackCursor, codebooks :&[Codebook],
112 fl :&FloorTypeZero) -> Result<(Vec<f32>, u64), FloorSpecialCase> {
113 // TODO this needs to become 128 bits wide, not just 64,
114 // as floor0_amplitude_bits can be up to 127.
115 let amplitude = try!(rdr.read_dyn_u64(fl.floor0_amplitude_bits));
116 if amplitude <= 0 {
117 // This channel is unused in this frame,
118 // its all zeros.
119 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 // Undecodable per spec
126 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 // Little optimisation: we don't have to care about the >= case here
136 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 // This rule makes sure that coefficients doesn't get
145 // larger than floor0_order and saves an allocation
146 // in this case
147 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
floor_zero_compute_curve(cos_coefficients :&[f32], amplitude :u64, fl :&FloorTypeZero, blockflag :bool, n :u16) -> Vec<f32>162 fn 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 // Compute p and q
174 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 // Compute linear_floor_value
198 let linear_floor_value = (0.11512925 *
199 (lfv_common_term / (p+q).sqrt() - fl.floor0_amplitude_offset as f32)
200 ).exp();
201
202 // Write into output
203 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
216 // Returns Err if the floor is "unused"
floor_one_decode(rdr :&mut BitpackCursor, codebooks :&[Codebook], fl :&FloorTypeOne) -> Result<Vec<u32>, FloorSpecialCase>217 fn floor_one_decode(rdr :&mut BitpackCursor, codebooks :&[Codebook],
218 fl :&FloorTypeOne) -> Result<Vec<u32>, FloorSpecialCase> {
219 // TODO perhaps it means invalid audio packet if reading the nonzero
220 // flag doesn't succeed bc end of packet. Perhaps it does not.
221 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
extr_neighbor<F>(v :&[u32], max_idx :usize, compare :F, relation :&str) -> (usize, u32) where F :Fn(u32, u32) -> std::cmp::Ordering255 fn 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 // First find a first index that fulfills
265 // the criterion of being "smaller" than bound
266 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 // Now search for "bigger" entries
273 let (offset, max_neighbor) = prefix[min_idx..].iter().cloned()
274 .enumerate()
275 // According to documentation of Iterator::max_by,
276 // "If several elements are equally maximum, the last element is returned".
277 // Thus, in order to find the *first* maximum element,
278 // we need to search from the end of `prefix`
279 .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
low_neighbor(v :&[u32], x :usize) -> (usize, u32)287 fn low_neighbor(v :&[u32], x :usize) -> (usize, u32) {
288 extr_neighbor(v, x, |a, b| a.cmp(&b), "smaller")
289 }
290
291
high_neighbor(v :&[u32], x :usize) -> (usize, u32)292 fn high_neighbor(v :&[u32], x :usize) -> (usize, u32) {
293 extr_neighbor(v, x, |a, b| b.cmp(&a), "bigger")
294 }
295
296 #[test]
test_low_neighbor()297 fn test_low_neighbor() {
298 let v = [1, 4, 2, 3, 6, 5];
299 // 0 will panic
300 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]
test_high_neighbor()309 fn test_high_neighbor() {
310 let v = [1, 4, 2, 3, 6, 5];
311 // 0, 1 will panic
312 assert_eq!(high_neighbor(&v, 2), (1, 4));
313 assert_eq!(high_neighbor(&v, 3), (1, 4));
314 // 4 will panic
315 assert_eq!(high_neighbor(&v, 5), (4, 6));
316 }
317
318 #[test]
test_high_neighbor_ex()319 fn test_high_neighbor_ex() {
320 // Data extracted from example file
321 let v = [0, 128, 12, 46, 4, 8, 16, 23,
322 33, 70, 2, 6, 10, 14, 19, 28, 39, 58, 90];
323
324 // 0, 1 will panic
325 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]
test_high_neighbor_panic()346 fn test_high_neighbor_panic() {
347 high_neighbor(&[1, 4, 3, 2, 6, 5], 4);
348 }
349
350 #[test]
351 #[should_panic]
test_low_neighbor_panic()352 fn test_low_neighbor_panic() {
353 low_neighbor(&[2, 4, 3, 1, 6, 5], 3);
354 }
355
render_point(x0 :u32, y0 :u32, x1 :u32, y1 :u32, x :u32) -> u32356 fn render_point(x0 :u32, y0 :u32, x1 :u32, y1 :u32, x :u32) -> u32 {
357 // TODO find out whether the type choices in this method are okay
358 // (esp. the i32 choice).
359 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]
test_render_point()372 fn test_render_point() {
373 // Test data taken from real life ogg/vorbis file.
374 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
floor_one_curve_compute_amplitude(floor1_y :&[u32], fl :&FloorTypeOne) -> (Vec<u32>, Vec<bool>)393 fn 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 // Clamp all entries of floor1_final_y to range
433 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
439 static 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
render_line(x0 :u32, y0 :u32, x1 :u32, y1 :u32, v :&mut Vec<u32>)505 fn render_line(x0 :u32, y0 :u32, x1 :u32, y1 :u32, v :&mut Vec<u32>) {
506 // TODO find out whether the type choices in this method are okay
507 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
floor_one_curve_synthesis(floor1_final_y :Vec<u32>, floor1_step2_flag :Vec<bool>, fl :&FloorTypeOne, n :u16) -> Vec<f32>528 fn 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
floor_decode<'a>(rdr :&mut BitpackCursor, ident :&IdentHeader, mapping :&Mapping, codebooks :&[Codebook], floors :&'a [Floor]) -> Result<Vec<DecodedFloor<'a>>, ()>559 fn 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
residue_packet_read_partition(rdr :&mut BitpackCursor, codebook :&Codebook, resid :&Residue, vec_v :&mut [f32]) -> Result<(), HuffmanVqReadErr>589 fn 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 // Common for both format 1 and 2
602 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
residue_packet_decode_inner(rdr :&mut BitpackCursor, cur_blocksize :u16, do_not_decode_flag :&[bool], resid :&Residue, codebooks :&[Codebook]) -> Result<Vec<f32>, ()>622 fn 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 // Older versions of the spec say max() here,
629 // but there's been a bug in the spec.
630 // It's been fixed since:
631 // https://github.com/xiph/vorbis/pull/35
632 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 // Allocate and zero all vectors that will be returned
642 let mut vectors = vec![0.; ch * actual_size];
643
644 if n_to_read == 0 {
645 // No residue to decode
646 return Ok(vectors);
647 }
648
649 if classwords_per_codeword == 0 {
650 // A value of 0 would create an infinite loop.
651 // Therefore, throw an error in this case.
652 try!(Err(()));
653 }
654
655 'pseudo_return: loop {
656 // ENdofpacketisnOrmal macro. Local replacement for try.
657 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 // codebook is checked by header decode to have a value mapping
696 // Decode the partition into output vector number j (vec_j).
697 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
722 // Ok means "fine" (or end of packet, but thats "fine" too!),
723 // Err means "not fine" -- the whole packet must be discarded
residue_packet_decode(rdr :&mut BitpackCursor, cur_blocksize :u16, do_not_decode_flag :&[bool], resid :&Residue, codebooks :&[Codebook]) -> Result<Vec<f32>, ()>724 fn 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 // Don't attempt to decode, but return vectors,
740 // as required per spec only residue 2 has this.
741 return Ok(vec![0.; ch * vec_size]);
742 } else {
743 // Construct a do_not_decode flag array
744 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 // Post decode step
751 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]
inverse_couple(m :f32, a :f32) -> (f32, f32)765 fn 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
781 // TODO this is probably slower than a replacement of
782 // this function in unsafe code, no idea
dual_mut_idx<T>(v :&mut [T], idx_a :usize, idx_b :usize) -> (&mut T, &mut T)783 fn 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
dct_iv_slow(buffer :&mut [f32])794 fn 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)]
inverse_mdct_slow(buffer :&mut [f32])811 fn 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); // returns -c'-d, a-b'
818 for i in 0 .. n4 {
819 buffer[i] = temp[i + n4]; // a-b'
820 }
821 for i in n4 .. n3_4 {
822 buffer[i] = -temp[n3_4 - i - 1]; // b-a', c+d'
823 }
824 for i in n3_4 .. n {
825 buffer[i] = -temp[i - n3_4]; // c'+d
826 }
827 }
828
829 #[cfg(test)]
830 #[test]
test_imdct_slow()831 fn 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
845 /// The right part of the previous window
846 ///
847 /// This is the only state that needs to be changed
848 /// once the headers are read.
849 pub struct PreviousWindowRight {
850 data :Option<Vec<Vec<f32>>>,
851 }
852
853 impl PreviousWindowRight {
854 /// Initialisation for new streams
new() -> Self855 pub fn new() -> Self {
856 return PreviousWindowRight{ data : None };
857 }
858 /// If the state is still uninitialized
is_empty(&self) -> bool859 pub fn is_empty(&self) -> bool {
860 self.data.is_none()
861 }
862 }
863
864 /**
865 Returns the per-channel sample count of a packet if it were decoded.
866
867 This operation is very cheap and doesn't involve actual decoding of the packet.
868
869 Note: for the first packet in a stream, or in other instances when
870 the `PreviousWindowRight` is reset, the decoding functions will return
871 0 samples for that packet, while this function returns a different number.
872 Please use the `PreviousWindowRight::is_empty` function or other methods
873 to check for this case.
874 */
get_decoded_sample_count(ident :&IdentHeader, setup :&SetupHeader, packet :&[u8]) -> Result<usize, AudioReadError>875 pub 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 // Compute windowing info for left window
891 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 // Compute windowing info for right window
901 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)]
913 /**
914 Main audio packet decoding function
915
916 Pass your info to this function to get your raw packet data decoded.
917
918 Panics if the passed PreviousWindowRight struct doesn't match the info
919 from the ident header.
920 */
read_audio_packet_generic<S :Samples>(ident :&IdentHeader, setup :&SetupHeader, packet :&[u8], pwr :&mut PreviousWindowRight) -> Result<S, AudioReadError>921 pub 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 // Decode the floors
942 let decoded_floor_infos = try!(floor_decode(&mut rdr, ident, mapping,
943 &setup.codebooks, &setup.floors));
944
945 // Now calculate the no_residue vector
946 let mut no_residue = TinyVec::<[bool; 32]>::new();
947 for fl in &decoded_floor_infos {
948 no_residue.push(fl.is_unused());
949 }
950 // and also propagate
951 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 // Residue decode.
960 let mut residue_vectors = vec![vec![]; mapping.mapping_mux.len()];
961 // Helper variable
962 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 // The vectors Vec<f32> now contains the do_not_decode_flag.len()
977 // many decoded residue vectors, each vector occupying n/2 scalars.
978 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 // TODO get rid of this copy somehow...
982 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 // Inverse coupling
993 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 // https://github.com/rust-lang/rfcs/issues/372
999 // grumble grumble...
1000 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 // Dot product
1009 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 // Generate zero'd floor of length n/2
1025 vec![0.; (n / 2) as usize]
1026 },
1027 };
1028
1029 // The only legal length is n/2.
1030 // The implementation should ensure this,
1031 // but its good for debugging to have this
1032 // confirmed.
1033 debug_assert_eq!(residue_vector.len(), (n / 2) as usize);
1034 debug_assert_eq!(floor_decoded.len(), (n / 2) as usize);
1035
1036 // Now do the multiplication
1037 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 // Inverse MDCT
1046 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_naive(cached_bd, &mut spectrum[..]);
1052 imdct::inverse_mdct(cached_bd, &mut spectrum[..], bs);
1053 //inverse_mdct_slow(&mut spectrum[..]);
1054 }
1055
1056 record_post_mdct!(audio_spectri);
1057
1058 // Compute windowing info for left window
1059 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 // Compute windowing info for right window
1069 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 /*println!("n={} prev_win_flag={:?} left_win_(start={}, end={}, n={}) right_win(start={}, end={})",
1078 n, previous_next_window_flag, left_win_start, left_win_end, left_n,
1079 right_win_start, right_win_end); // */
1080
1081 // Overlap add and store last half
1082 // in PreviousWindowRight
1083 // Only add if prev has elements.
1084 let mut future_prev_halves = Vec::with_capacity(ident.audio_channels as usize);
1085 if let Some(prev_data) = pwr.data.take() {
1086 // TODO maybe check if prev_n matches blocksize_0 or blocksize_1,
1087 // and the channel number. Panic if no match of either.
1088 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 // Then do the actual overlap_add
1099 // Set up iterators for all the variables
1100 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 // According to fuzzing, code can trigger this case,
1111 // so let's error gracefully instead of panicing.
1112 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 // and populate the future previous half
1123 let future_prev_half = chan[right_win_start..right_win_end].into();
1124
1125 future_prev_halves.push(future_prev_half);
1126
1127 // Remove everything left of the left window start,
1128 // by moving the the stuff right to it to the left.
1129 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 // Now the last step: truncate the decoded packet
1136 // to cut off the right part.
1137 chan.truncate(right_win_start - left_win_start);
1138 // TODO stb_vorbis doesn't use right_win_start
1139 // in the calculation above but sth like
1140 // if len < right_win_start { len } else { right_win_start }
1141 }
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 // If there is no previous window right, we have to discard
1151 // the whole packet.
1152 chan.truncate(0);
1153 }
1154 }
1155
1156 pwr.data = Some(future_prev_halves);
1157
1158 // Generate final integer samples
1159 let final_i16_samples = S::from_floats(audio_spectri);
1160
1161 Ok(final_i16_samples)
1162 }
1163
1164 /**
1165 Main audio packet decoding function
1166
1167 Pass your info to this function to get your raw packet data decoded.
1168
1169 Panics if the passed PreviousWindowRight struct doesn't match the info
1170 from the ident header.
1171 */
read_audio_packet(ident :&IdentHeader, setup :&SetupHeader, packet :&[u8], pwr :&mut PreviousWindowRight) -> Result<Vec<Vec<i16>>, AudioReadError>1172 pub 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 }
1176