1use crate::bits::BitReader;
4use crate::mdct::Imdct;
5use crate::tables;
6use crate::vlc::Vlc;
7use crate::{Error, Params, Result};
8
9const BLOCK_MIN_BITS: u32 = 7;
10const NOISE_TAB_SIZE: usize = 8192;
11const MAX_RESERVOIR_BYTES: usize = 1 << 15;
12
13struct Layout {
15 exponent_bands: Vec<usize>,
17 coefs_end: usize,
19 high_band_start: usize,
21 high_bands: Vec<usize>,
23}
24
25#[derive(Default)]
26struct Channel {
27 coded: bool,
28 exponents: Vec<f32>,
30 exp_bsize: usize,
31 exp_ready: bool,
32 max_exponent: f32,
33 levels: Vec<f32>,
35 spectrum: Vec<f32>,
36 high_band_coded: Vec<bool>,
37 high_band_values: Vec<i32>,
38 frame_out: Vec<f32>,
40}
41
42pub struct Decoder {
45 channels: usize,
46 sample_rate: u32,
47 frame_len_bits: u32,
48 frame_len: usize,
49 nb_block_sizes: usize,
50 use_exp_vlc: bool,
51 use_bit_reservoir: bool,
52 use_variable_block_len: bool,
53 use_noise_coding: bool,
54 byte_offset_bits: u32,
55 noise_mult: f32,
56 noise_table: Vec<f32>,
57 noise_index: usize,
58 layouts: Vec<Layout>,
59 coef_vlc: [Vlc; 2],
60 coef_runlevel: [&'static [(u16, u16)]; 2],
61 exp_vlc: Vlc,
62 hgain_vlc: Vlc,
63 imdct: Vec<Imdct>,
64 windows: Vec<Vec<f32>>,
65 imdct_out: Vec<f32>,
66 ch: Vec<Channel>,
67
68 reset_block_lengths: bool,
69 prev_block_len_bits: u32,
70 block_len_bits: u32,
71 next_block_len_bits: u32,
72 block_pos: usize,
73 ms_stereo: bool,
74
75 reservoir: Vec<u8>,
77 reservoir_bit: u32,
78 skip: usize,
80}
81
82impl Decoder {
83 pub fn new(p: &Params) -> Result<Self> {
86 if p.tag != crate::WMAV2 {
87 return Err(Error::Unsupported(
88 "only WMA v2 (format tag 0x161) is supported",
89 ));
90 }
91 if !(1..=2).contains(&p.channels) {
92 return Err(Error::Unsupported("only mono and stereo are supported"));
93 }
94 if p.sample_rate == 0 || p.sample_rate > 50_000 || p.block_align == 0 {
95 return Err(Error::Invalid("bad sample rate or block align"));
96 }
97 let use_exp_vlc = p.flags & 1 != 0;
98 if !use_exp_vlc {
99 return Err(Error::Unsupported("LSP-coded exponents"));
100 }
101 let channels = usize::from(p.channels);
102 let sample_rate = p.sample_rate;
103 let bit_rate = p.avg_bytes_per_sec as f32 * 8.0;
104
105 let frame_len_bits = if sample_rate <= 16_000 {
106 9
107 } else if sample_rate <= 22_050 {
108 10
109 } else {
110 11
111 };
112 let frame_len = 1usize << frame_len_bits;
113
114 let use_variable_block_len = p.flags & 4 != 0;
115 let nb_block_sizes = if use_variable_block_len {
116 let mut nb = u32::from((p.flags >> 3) & 3) + 1;
117 if bit_rate / channels as f32 >= 32_000.0 {
118 nb += 2;
119 }
120 nb.min(frame_len_bits - BLOCK_MIN_BITS) as usize + 1
121 } else {
122 1
123 };
124
125 let rate_class = [44_100, 22_050, 16_000, 11_025, 8_000]
127 .into_iter()
128 .find(|&r| sample_rate >= r)
129 .unwrap_or(sample_rate);
130 let bps = bit_rate / (channels as f32 * sample_rate as f32);
131 let bps1 = if channels == 2 { bps * 1.6 } else { bps };
132 let byte_offset_bits = ((bps * frame_len as f32 / 8.0 + 0.5) as u32).max(1).ilog2() + 2;
133
134 let mut use_noise_coding = true;
135 let mut high_freq = sample_rate as f32 * 0.5;
136 match rate_class {
137 44_100 => {
138 if bps1 >= 0.61 {
139 use_noise_coding = false;
140 } else {
141 high_freq *= 0.4;
142 }
143 }
144 22_050 => {
145 if bps1 >= 1.16 {
146 use_noise_coding = false;
147 } else if bps1 >= 0.72 {
148 high_freq *= 0.7;
149 } else {
150 high_freq *= 0.6;
151 }
152 }
153 16_000 => high_freq *= if bps > 0.5 { 0.5 } else { 0.3 },
154 11_025 => high_freq *= 0.7,
155 8_000 => {
156 if bps <= 0.625 {
157 high_freq *= 0.5;
158 } else if bps > 0.75 {
159 use_noise_coding = false;
160 } else {
161 high_freq *= 0.65;
162 }
163 }
164 _ => {
165 high_freq *= if bps >= 0.8 {
166 0.75
167 } else if bps >= 0.6 {
168 0.6
169 } else {
170 0.5
171 }
172 }
173 }
174
175 let layouts = (0..nb_block_sizes)
176 .map(|k| layout(sample_rate, frame_len_bits, k as u32, high_freq))
177 .collect();
178
179 let noise_mult = 0.02f32; let noise_table = if use_noise_coding {
181 let norm = (1.0 / (1u64 << 31) as f32) * 3f32.sqrt() * noise_mult;
182 let mut seed = 1u32;
183 (0..NOISE_TAB_SIZE)
184 .map(|_| {
185 seed = seed.wrapping_mul(314_159).wrapping_add(1);
186 seed as i32 as f32 * norm
187 })
188 .collect()
189 } else {
190 Vec::new()
191 };
192
193 let class = if sample_rate >= 32_000 && bps1 < 0.72 {
194 0
195 } else if sample_rate >= 32_000 && bps1 < 1.16 {
196 1
197 } else {
198 2
199 };
200 let (codes, runlevel) = COEF_TABLES[class];
201
202 let windows = (0..nb_block_sizes)
203 .map(|k| {
204 let n = frame_len >> k;
205 (0..n)
206 .map(|i| {
207 ((i as f64 + 0.5) * std::f64::consts::PI / (2.0 * n as f64)).sin() as f32
208 })
209 .collect()
210 })
211 .collect();
212 let ch = (0..channels)
213 .map(|_| Channel {
214 exponents: vec![0.0; frame_len],
215 levels: vec![0.0; frame_len],
216 spectrum: vec![0.0; frame_len],
217 high_band_coded: vec![false; 32],
218 high_band_values: vec![0; 32],
219 frame_out: vec![0.0; frame_len * 2],
220 ..Channel::default()
221 })
222 .collect();
223
224 Ok(Decoder {
225 channels,
226 sample_rate,
227 frame_len_bits,
228 frame_len,
229 nb_block_sizes,
230 use_exp_vlc,
231 use_bit_reservoir: p.flags & 2 != 0,
232 use_variable_block_len,
233 use_noise_coding,
234 byte_offset_bits,
235 noise_mult,
236 noise_table,
237 noise_index: 0,
238 layouts,
239 coef_vlc: [Vlc::new(codes[0]), Vlc::new(codes[1])],
240 coef_runlevel: runlevel,
241 exp_vlc: Vlc::new(&tables::EXP_CODES),
242 hgain_vlc: Vlc::new(&tables::HGAIN_CODES),
243 imdct: (0..nb_block_sizes)
244 .map(|k| Imdct::new(frame_len >> k))
245 .collect(),
246 windows,
247 imdct_out: vec![0.0; frame_len * 2],
248 ch,
249 reset_block_lengths: true,
250 prev_block_len_bits: frame_len_bits,
251 block_len_bits: frame_len_bits,
252 next_block_len_bits: frame_len_bits,
253 block_pos: 0,
254 ms_stereo: false,
255 reservoir: Vec::new(),
256 reservoir_bit: 0,
257 skip: 2 * frame_len,
258 })
259 }
260
261 pub fn channels(&self) -> usize {
263 self.channels
264 }
265
266 pub fn sample_rate(&self) -> u32 {
268 self.sample_rate
269 }
270
271 pub fn delay(&self) -> usize {
274 2 * self.frame_len
275 }
276
277 pub fn frame_len(&self) -> usize {
279 self.frame_len
280 }
281
282 pub fn decode_packet(&mut self, packet: &[u8], out: &mut Vec<f32>) -> Result<()> {
286 let (start, skip) = (out.len(), self.skip);
287 let r = self.superframe(packet, out);
288 if r.is_err() {
289 out.truncate(start);
290 self.skip = skip;
291 self.reservoir.clear();
292 }
293 r
294 }
295
296 pub fn flush(&mut self, out: &mut Vec<f32>) {
298 self.emit_frame(out);
299 self.reset();
300 }
301
302 pub fn reset(&mut self) {
304 for c in &mut self.ch {
305 c.frame_out.fill(0.0);
306 c.exp_ready = false;
307 }
308 self.reservoir.clear();
309 self.reset_block_lengths = true;
310 self.noise_index = 0;
311 self.skip = self.delay();
312 }
313
314 fn superframe(&mut self, packet: &[u8], out: &mut Vec<f32>) -> Result<()> {
315 let mut br = BitReader::new(packet);
316 if !self.use_bit_reservoir {
317 self.reset_block_lengths = true;
318 return self.frame(&mut br, out);
319 }
320 br.skip(4); let mut nb_frames = br.bits(4) as i32 - i32::from(self.reservoir.is_empty());
323 if nb_frames < 0 || (nb_frames == 0 && packet.len() <= 2) {
324 return Err(Error::Invalid("superframe without a frame end"));
325 }
326 if nb_frames == 0 {
327 if self.reservoir.len() + packet.len() > MAX_RESERVOIR_BYTES {
329 return Err(Error::Invalid("bit reservoir overflow"));
330 }
331 self.reservoir.extend_from_slice(&packet[1..]);
332 return Ok(());
333 }
334 let bit_offset = br.bits(self.byte_offset_bits + 3) as usize;
335 let header_bits = br.pos();
336
337 if !self.reservoir.is_empty() {
338 let mut buf = std::mem::take(&mut self.reservoir);
339 if buf.len() + bit_offset.div_ceil(8) > MAX_RESERVOIR_BYTES {
340 return Err(Error::Invalid("bit reservoir overflow"));
341 }
342 let mut left = bit_offset as u32;
343 while left >= 8 {
344 buf.push(br.bits(8) as u8);
345 left -= 8;
346 }
347 if left > 0 {
348 buf.push((br.bits(left) << (8 - left)) as u8);
349 }
350 let mut fr = BitReader::new(&buf);
351 fr.skip(self.reservoir_bit);
352 self.frame(&mut fr, out)?;
353 nb_frames -= 1;
354 }
355
356 let pos = header_bits + bit_offset;
357 if pos > br.len_bits() {
358 return Err(Error::Invalid("frame offset past end of packet"));
359 }
360 br.seek(pos);
361 self.reset_block_lengths = true;
362 for _ in 0..nb_frames {
363 self.frame(&mut br, out)?;
364 }
365 let tail = br.pos();
366 if tail > br.len_bits() || packet.len() - tail / 8 > MAX_RESERVOIR_BYTES {
367 return Err(Error::Invalid("frame overran packet"));
368 }
369 self.reservoir = packet[tail / 8..].to_vec();
370 self.reservoir_bit = (tail % 8) as u32;
371 Ok(())
372 }
373
374 fn frame(&mut self, br: &mut BitReader, out: &mut Vec<f32>) -> Result<()> {
375 self.block_pos = 0;
376 while !self.block(br)? {}
377 self.emit_frame(out);
378 let f = self.frame_len;
379 for c in &mut self.ch {
380 c.frame_out.copy_within(f..2 * f, 0);
381 }
382 Ok(())
383 }
384
385 fn emit_frame(&mut self, out: &mut Vec<f32>) {
386 const SCALE: f32 = 1.0 / 32768.0;
387 let first = self.skip.min(self.frame_len);
388 self.skip -= first;
389 out.reserve((self.frame_len - first) * self.channels);
390 for i in first..self.frame_len {
391 for c in &self.ch {
392 out.push(c.frame_out[i] * SCALE);
393 }
394 }
395 }
396
397 fn block(&mut self, br: &mut BitReader) -> Result<bool> {
399 let fb = self.frame_len_bits;
400 if self.use_variable_block_len {
401 let n = (self.nb_block_sizes as u32 - 1).ilog2() + 1;
402 let size_bits = |br: &mut BitReader| {
403 let v = br.bits(n) as usize;
404 if v >= self.nb_block_sizes {
405 return Err(Error::Invalid("block size index out of range"));
406 }
407 Ok(fb - v as u32)
408 };
409 if self.reset_block_lengths {
410 self.reset_block_lengths = false;
411 self.prev_block_len_bits = size_bits(br)?;
412 self.block_len_bits = size_bits(br)?;
413 } else {
414 self.prev_block_len_bits = self.block_len_bits;
415 self.block_len_bits = self.next_block_len_bits;
416 }
417 self.next_block_len_bits = size_bits(br)?;
418 } else {
419 self.prev_block_len_bits = fb;
420 self.block_len_bits = fb;
421 self.next_block_len_bits = fb;
422 }
423 let bsize = (fb - self.block_len_bits) as usize;
424 let block_len = 1usize << self.block_len_bits;
425 if self.block_pos + block_len > self.frame_len {
426 return Err(Error::Invalid("block runs past frame end"));
427 }
428
429 if self.channels == 2 {
430 self.ms_stereo = br.bit();
431 }
432 let mut any_coded = false;
433 for c in &mut self.ch {
434 c.coded = br.bit();
435 any_coded |= c.coded;
436 }
437 if any_coded {
438 self.decode_spectrum(br, bsize, block_len)?;
439 }
440
441 let half = block_len / 2;
442 let index = self.frame_len / 2 + self.block_pos - half;
443 for ci in 0..self.channels {
444 if self.ch[ci].coded {
445 self.imdct[bsize].run(&self.ch[ci].spectrum[..block_len], &mut self.imdct_out);
446 } else if !(self.ms_stereo && ci == 1) {
447 self.imdct_out.fill(0.0);
449 }
450 self.window(ci, index);
451 }
452
453 self.block_pos += block_len;
454 Ok(self.block_pos >= self.frame_len)
455 }
456
457 fn decode_spectrum(
458 &mut self,
459 br: &mut BitReader,
460 bsize: usize,
461 block_len: usize,
462 ) -> Result<()> {
463 let mut total_gain = 1i32;
464 loop {
465 if br.pos() + 7 > br.len_bits() {
466 return Err(Error::Invalid("truncated gain"));
467 }
468 let a = br.bits(7) as i32;
469 total_gain += a;
470 if a != 127 {
471 break;
472 }
473 }
474 let coef_nb_bits = match total_gain {
475 ..15 => 13,
476 15..32 => 12,
477 32..40 => 11,
478 40..45 => 10,
479 _ => 9,
480 };
481
482 let layout = &self.layouts[bsize];
483 let mut nb_coefs = [layout.coefs_end; 2];
484
485 if self.use_noise_coding {
486 let n = layout.high_bands.len();
487 for (ci, c) in self.ch.iter_mut().enumerate() {
488 if c.coded {
489 for i in 0..n {
490 c.high_band_coded[i] = br.bit();
491 if c.high_band_coded[i] {
492 nb_coefs[ci] -= layout.high_bands[i];
493 }
494 }
495 }
496 }
497 for c in self.ch.iter_mut().filter(|c| c.coded) {
498 let mut val: Option<i32> = None;
499 for i in 0..n {
500 if c.high_band_coded[i] {
501 let v = match val {
502 None => br.bits(7) as i32 - 19,
503 Some(v) => v + i32::from(self.hgain_vlc.read(br).unwrap_or(0)) - 18,
504 };
505 val = Some(v);
506 c.high_band_values[i] = v;
507 }
508 }
509 }
510 }
511
512 if self.block_len_bits == self.frame_len_bits || br.bit() {
514 for ci in 0..self.channels {
515 if self.ch[ci].coded {
516 self.decode_exponents(br, ci, bsize, block_len)?;
517 }
518 }
519 }
520 if self.ch.iter().any(|c| c.coded && !c.exp_ready) {
521 return Err(Error::Invalid("exponents used before being sent"));
522 }
523
524 for ci in 0..self.channels {
525 if !self.ch[ci].coded {
526 continue;
527 }
528 let t = usize::from(ci == 1 && self.ms_stereo);
529 let levels = &mut self.ch[ci].levels[..block_len];
530 levels.fill(0.0);
531 run_level(
532 br,
533 &self.coef_vlc[t],
534 self.coef_runlevel[t],
535 levels,
536 nb_coefs[ci],
537 self.frame_len_bits,
538 coef_nb_bits,
539 );
540 }
541
542 let mdct_norm = 1.0 / (block_len / 2) as f32;
543 let gain = 10f32.powf(total_gain as f32 * 0.05);
544 for ci in 0..self.channels {
545 if self.ch[ci].coded {
546 let mult = gain / self.ch[ci].max_exponent * mdct_norm;
547 if self.use_noise_coding {
548 self.dequantise_with_noise(ci, bsize, block_len, mult, mdct_norm);
549 } else {
550 let c = &mut self.ch[ci];
551 let esize = c.exp_bsize;
552 let n = nb_coefs[ci];
553 for i in 0..n {
554 c.spectrum[i] = c.levels[i] * c.exponents[(i << bsize) >> esize] * mult;
555 }
556 c.spectrum[n..block_len].fill(0.0);
557 }
558 }
559 }
560
561 if self.ms_stereo && self.ch[1].coded {
562 if !self.ch[0].coded {
563 self.ch[0].spectrum[..block_len].fill(0.0);
564 self.ch[0].coded = true;
565 }
566 let (a, b) = self.ch.split_at_mut(1);
567 for (m, s) in a[0].spectrum[..block_len]
568 .iter_mut()
569 .zip(&mut b[0].spectrum[..block_len])
570 {
571 let (l, r) = (*m + *s, *m - *s);
572 *m = l;
573 *s = r;
574 }
575 }
576 Ok(())
577 }
578
579 fn decode_exponents(
580 &mut self,
581 br: &mut BitReader,
582 ci: usize,
583 bsize: usize,
584 block_len: usize,
585 ) -> Result<()> {
586 debug_assert!(self.use_exp_vlc);
587 let c = &mut self.ch[ci];
588 let mut last = 36i32;
589 let mut max = 0f32;
590 let mut q = 0;
591 for &width in &self.layouts[bsize].exponent_bands {
592 if q >= block_len {
593 break;
594 }
595 let code = self
596 .exp_vlc
597 .read(br)
598 .ok_or(Error::Invalid("bad exponent code"))?;
599 last += i32::from(code) - 60;
600 if !(-60..=195).contains(&last) {
601 return Err(Error::Invalid("exponent out of range"));
602 }
603 let v = 10f64.powf(f64::from(last) / 16.0) as f32;
604 max = max.max(v);
605 c.exponents[q..q + width].fill(v);
606 q += width;
607 }
608 c.max_exponent = max;
609 c.exp_bsize = bsize;
610 c.exp_ready = true;
611 Ok(())
612 }
613
614 fn dequantise_with_noise(
616 &mut self,
617 ci: usize,
618 bsize: usize,
619 block_len: usize,
620 mult: f32,
621 mdct_norm: f32,
622 ) {
623 let layout = &self.layouts[bsize];
624 let c = &mut self.ch[ci];
625 let esize = c.exp_bsize;
626 let exp_at = |pos: usize| (pos << bsize) >> esize;
627 let mut noise = || {
628 let v = self.noise_table[self.noise_index];
629 self.noise_index = (self.noise_index + 1) & (NOISE_TAB_SIZE - 1);
630 v
631 };
632
633 let n_high = layout.high_bands.len();
635 let mut power = [0f32; 32];
636 let mut last_high = 0;
637 let mut e = exp_at(layout.high_band_start);
638 for j in 0..n_high {
639 let n = layout.high_bands[j];
640 if c.high_band_coded[j] {
641 let sum: f32 = (0..n).map(|i| c.exponents[e + exp_at(i)].powi(2)).sum();
642 power[j] = sum / n as f32;
643 last_high = j;
644 }
645 e += exp_at(n);
646 }
647
648 let mut out = 0;
649 let mut levels = 0;
650 let mut e = 0;
651 for j in -1..n_high as i32 {
652 let n = if j < 0 {
653 layout.high_band_start
654 } else {
655 layout.high_bands[j as usize]
656 };
657 if j >= 0 && c.high_band_coded[j as usize] {
658 let j = j as usize;
659 let m = (power[j] / power[last_high]).sqrt()
660 * 10f32.powf(c.high_band_values[j] as f32 * 0.05)
661 / (c.max_exponent * self.noise_mult)
662 * mdct_norm;
663 for i in 0..n {
664 c.spectrum[out] = noise() * c.exponents[e + exp_at(i)] * m;
665 out += 1;
666 }
667 } else {
668 for i in 0..n {
669 c.spectrum[out] =
670 (c.levels[levels] + noise()) * c.exponents[e + exp_at(i)] * mult;
671 out += 1;
672 levels += 1;
673 }
674 }
675 e += exp_at(n);
676 }
677 let m = mult * c.exponents[e - exp_at(1).max(1)];
678 while out < block_len {
679 c.spectrum[out] = noise() * m;
680 out += 1;
681 }
682 }
683
684 fn window(&mut self, ci: usize, index: usize) {
686 let fb = self.frame_len_bits;
687 let block_len = 1usize << self.block_len_bits;
688 let input = &self.imdct_out;
689 let out = &mut self.ch[ci].frame_out[index..index + 2 * block_len];
690
691 if self.block_len_bits <= self.prev_block_len_bits {
692 let w = &self.windows[(fb - self.block_len_bits) as usize];
693 for i in 0..block_len {
694 out[i] += input[i] * w[i];
695 }
696 } else {
697 let len = 1usize << self.prev_block_len_bits;
698 let n = (block_len - len) / 2;
699 let w = &self.windows[(fb - self.prev_block_len_bits) as usize];
700 for i in 0..len {
701 out[n + i] += input[n + i] * w[i];
702 }
703 out[n + len..block_len].copy_from_slice(&input[n + len..block_len]);
704 }
705
706 let (out, input) = (&mut out[block_len..], &input[block_len..]);
707 if self.block_len_bits <= self.next_block_len_bits {
708 let w = &self.windows[(fb - self.block_len_bits) as usize];
709 for i in 0..block_len {
710 out[i] = input[i] * w[block_len - 1 - i];
711 }
712 } else {
713 let len = 1usize << self.next_block_len_bits;
714 let n = (block_len - len) / 2;
715 let w = &self.windows[(fb - self.next_block_len_bits) as usize];
716 out[..n].copy_from_slice(&input[..n]);
717 for i in 0..len {
718 out[n + i] = input[n + i] * w[len - 1 - i];
719 }
720 out[n + len..block_len].fill(0.0);
721 }
722 }
723}
724
725type CoefTables = ([&'static [(u8, u32)]; 2], [&'static [(u16, u16)]; 2]);
726const COEF_TABLES: [CoefTables; 3] = [
727 (
728 [&tables::COEF0_CODES, &tables::COEF1_CODES],
729 [&tables::COEF0_RUNLEVEL, &tables::COEF1_RUNLEVEL],
730 ),
731 (
732 [&tables::COEF2_CODES, &tables::COEF3_CODES],
733 [&tables::COEF2_RUNLEVEL, &tables::COEF3_RUNLEVEL],
734 ),
735 (
736 [&tables::COEF4_CODES, &tables::COEF5_CODES],
737 [&tables::COEF4_RUNLEVEL, &tables::COEF5_RUNLEVEL],
738 ),
739];
740
741fn run_level(
743 br: &mut BitReader,
744 vlc: &Vlc,
745 runlevel: &[(u16, u16)],
746 levels: &mut [f32],
747 num: usize,
748 frame_len_bits: u32,
749 coef_nb_bits: u32,
750) {
751 let mask = levels.len() - 1;
752 let mut offset = 0usize;
753 while offset < num {
754 match vlc.read(br) {
755 Some(1) => break, Some(code @ 2..) => {
757 let (run, level) = runlevel[usize::from(code) - 2];
758 offset += usize::from(run);
759 let level = f32::from(level);
760 levels[offset & mask] = if br.bit() { level } else { -level };
761 }
762 _ => {
763 let level = br.bits(coef_nb_bits) as f32;
765 offset += br.bits(frame_len_bits) as usize;
766 levels[offset & mask] = if br.bit() { level } else { -level };
767 }
768 }
769 offset += 1;
770 }
771}
772
773fn layout(sample_rate: u32, frame_len_bits: u32, k: u32, high_freq: f32) -> Layout {
774 let frame_len = 1usize << frame_len_bits;
775 let block_len = frame_len >> k;
776
777 let arm = match sample_rate {
778 44_100.. => Some(0),
779 32_000.. => Some(1),
780 22_050.. => Some(2),
781 _ => None,
782 };
783 let hard = (frame_len_bits - BLOCK_MIN_BITS)
784 .checked_sub(k)
785 .filter(|&a| a < 3)
786 .zip(arm)
787 .and_then(|(a, arm)| tables::EXPONENT_BAND_EDGES[arm][a as usize]);
788 let exponent_bands: Vec<usize> = match hard {
789 Some(edges) => edges.windows(2).map(|w| usize::from(w[1] - w[0])).collect(),
790 None => {
791 let mut bands = Vec::new();
793 let mut last = 0;
794 for &f in &tables::CRITICAL_FREQS {
795 let b = u64::from(sample_rate);
796 let pos = (((block_len as u64 * 2 * u64::from(f)) + (b << 1)) / (4 * b)) << 2;
797 let pos = (pos as usize).min(block_len);
798 if pos > last {
799 bands.push(pos - last);
800 }
801 if pos >= block_len {
802 break;
803 }
804 last = pos;
805 }
806 bands
807 }
808 };
809
810 let coefs_end = (frame_len - frame_len * 9 / 100) >> k;
811 let high_band_start =
812 ((block_len as f32 * 2.0 * high_freq) / sample_rate as f32 + 0.5) as usize;
813 let mut high_bands = Vec::new();
814 let mut pos = 0;
815 for &w in &exponent_bands {
816 let start = pos.max(high_band_start);
817 pos += w;
818 let end = pos.min(coefs_end);
819 if end > start {
820 high_bands.push(end - start);
821 }
822 }
823 Layout {
824 exponent_bands,
825 coefs_end,
826 high_band_start,
827 high_bands,
828 }
829}