Skip to main content

wmv_decoder/wma/
decoder.rs

1use std::f32;
2
3use crate::asf::AudioStreamInfo;
4use crate::error::{DecoderError, Result};
5
6use super::bitstream::GetBitContext;
7use super::common::ff_wma_get_frame_len_bits;
8use super::mdct::MdctNaive;
9use super::tables;
10use super::vlc::{Vlc, VlcElem, ff_vlc_init_from_lengths, ff_vlc_init_sparse, get_vlc2};
11
12const BLOCK_MIN_BITS: i32 = 7;
13const BLOCK_MAX_BITS: i32 = 11;
14const BLOCK_MAX_SIZE: usize = 1 << BLOCK_MAX_BITS;
15const BLOCK_NB_SIZES: usize = (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) as usize;
16
17const HIGH_BAND_MAX_SIZE: usize = 16;
18const NB_LSP_COEFS: usize = 10;
19
20const MAX_CODED_SUPERFRAME_SIZE: usize = 32768;
21const MAX_CHANNELS: usize = 2;
22
23const NOISE_TAB_SIZE: usize = 8192;
24const LSP_POW_BITS: usize = 7;
25
26const VLCBITS: i32 = 9;
27const VLCMAX: i32 = (22 + VLCBITS - 1) / VLCBITS;
28
29const EXPVLCBITS: i32 = 8;
30const EXPMAX: i32 = (19 + EXPVLCBITS - 1) / EXPVLCBITS;
31
32const HGAINVLCBITS: i32 = 9;
33const HGAINMAX: i32 = (13 + HGAINVLCBITS - 1) / HGAINVLCBITS;
34
35/// Translate FFmpeg's `ptab[last_exp]`, where `ptab = pow_tab + 60`,
36/// into a bounds-checked Rust index into the full POW_TAB.  Negative
37/// exponents down to -60 are valid: e.g. `ptab[-1]` is `pow_tab[59]`.
38fn exponent_pow_tab_index(last_exp: i32) -> Option<usize> {
39    let idx = last_exp.checked_add(60)?;
40    let idx = usize::try_from(idx).ok()?;
41    (idx < tables::POW_TAB.len()).then_some(idx)
42}
43
44/// A decoded PCM chunk.
45#[derive(Debug, Clone)]
46pub struct PcmFrameF32 {
47    pub pts_ms: u32,
48    pub sample_rate: u32,
49    pub channels: u16,
50    /// Interleaved samples.
51    pub samples: Vec<f32>,
52}
53
54#[derive(Clone, Copy, Debug)]
55enum WmaVersion {
56    V1,
57    V2,
58}
59
60impl WmaVersion {
61    fn id(&self) -> i32 {
62        match self {
63            WmaVersion::V1 => 1,
64            WmaVersion::V2 => 2,
65        }
66    }
67}
68
69/// Direct translation of upstream `WMACodecContext` for WMAv1/2.
70pub struct WmaDecoder {
71    version: WmaVersion,
72
73    channels: usize,
74    sample_rate: u32,
75    bit_rate: u32,
76    block_align: u16,
77
78    // Flags derived from `flags2`.
79    use_exp_vlc: bool,
80    use_bit_reservoir: bool,
81    use_variable_block_len: bool,
82    use_noise_coding: bool,
83
84    byte_offset_bits: i32,
85
86    // VLC tables.
87    exp_vlc: Vlc,
88    hgain_vlc: Vlc,
89    coef_vlc: [Vlc; 2],
90    run_table: [Vec<u16>; 2],
91    level_table: [Vec<f32>; 2],
92
93    // Frame / block config.
94    frame_len_bits: i32,
95    frame_len: usize,
96    nb_block_sizes: usize,
97
98    reset_block_lengths: bool,
99    block_len_bits: i32,
100    next_block_len_bits: i32,
101    prev_block_len_bits: i32,
102    block_len: usize,
103    block_num: i32,
104    block_pos: usize,
105
106    ms_stereo: bool,
107    channel_coded: [bool; MAX_CHANNELS],
108
109    // Exponent bands.
110    exponent_sizes: [usize; BLOCK_NB_SIZES],
111    exponent_bands: [[u16; 25]; BLOCK_NB_SIZES],
112    high_band_start: [usize; BLOCK_NB_SIZES],
113    coefs_start: usize,
114    coefs_end: [usize; BLOCK_NB_SIZES],
115    exponent_high_sizes: [usize; BLOCK_NB_SIZES],
116    exponent_high_bands: [[u16; HIGH_BAND_MAX_SIZE]; BLOCK_NB_SIZES],
117
118    high_band_coded: [[bool; HIGH_BAND_MAX_SIZE]; MAX_CHANNELS],
119    high_band_values: [[i32; HIGH_BAND_MAX_SIZE]; MAX_CHANNELS],
120
121    // Exponents and coefficients.
122    exponents_bsize: [usize; MAX_CHANNELS],
123    exponents: [Vec<f32>; MAX_CHANNELS],
124    max_exponent: [f32; MAX_CHANNELS],
125    coefs1: [Vec<f32>; MAX_CHANNELS],
126    coefs: [Vec<f32>; MAX_CHANNELS],
127
128    // MDCT.
129    mdct: Vec<MdctNaive>,
130    windows: Vec<Vec<f32>>, // per block-size: half window of length block_len
131    output: Vec<f32>,       // 2*BLOCK_MAX_SIZE
132    frame_out: [Vec<f32>; MAX_CHANNELS],
133
134    // Bit reservoir.
135    last_superframe: Vec<u8>,
136    last_bitoffset: usize,
137    last_superframe_len: usize,
138
139    // ASF media objects are not guaranteed to be one codec packet each.
140    // WMAv1/v2 itself is block_align packetized, so retain bytes until a
141    // complete codec packet is available instead of silently truncating an
142    // assembled ASF object to its first block_align bytes.
143    pending_packet_bytes: Vec<u8>,
144    pending_packet_pts_ms: Option<u32>,
145    eof_done: bool,
146
147    // Noise.
148    noise_table: Vec<f32>,
149    noise_index: usize,
150    noise_mult: f32,
151
152    // LSP to curve.
153    lsp_cos_table: Vec<f32>,
154    lsp_pow_e_table: [f32; 256],
155    lsp_pow_m_table1: [f32; 1 << LSP_POW_BITS],
156    lsp_pow_m_table2: [f32; 1 << LSP_POW_BITS],
157
158    exponents_initialized: [bool; MAX_CHANNELS],
159}
160
161fn ilog2_u32(x: u32) -> i32 {
162    31 - (x.leading_zeros() as i32)
163}
164
165fn ff_exp10f(x: f32) -> f32 {
166    // ff_exp10f(x) = exp2f(M_LOG2_10 * x)
167    (std::f32::consts::LOG2_10 * x).exp2()
168}
169
170fn sine_window_init(n: usize) -> Vec<f32> {
171    // Translated from ff_sine_window_init.
172    let mut w = vec![0f32; n];
173    let den = 2.0f32 * n as f32;
174    for i in 0..n {
175        w[i] = ((i as f32 + 0.5) * (std::f32::consts::PI / den)).sin();
176    }
177    w
178}
179
180fn vector_fmul_reverse(dst: &mut [f32], src0: &[f32], win: &[f32]) {
181    let len = dst.len();
182    for i in 0..len {
183        dst[i] = src0[i] * win[len - 1 - i];
184    }
185}
186
187fn butterflies_float(v1: &mut [f32], v2: &mut [f32]) {
188    for i in 0..v1.len() {
189        let t = v1[i] - v2[i];
190        v1[i] += v2[i];
191        v2[i] = t;
192    }
193}
194
195fn pow_m1_4_tables(
196    x: f32,
197    lsp_pow_e_table: &[f32; 256],
198    lsp_pow_m_table1: &[f32; 1 << LSP_POW_BITS],
199    lsp_pow_m_table2: &[f32; 1 << LSP_POW_BITS],
200) -> f32 {
201    // Direct translation of `pow_m1_4` from upstream wmadec.c, but parameterized to avoid borrowing `self`.
202    let u = x.to_bits();
203    let e = (u >> 23) as usize;
204    let m = ((u >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1) as u32) as usize;
205    let t_bits = ((u << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23);
206    let t = f32::from_bits(t_bits);
207    let a = lsp_pow_m_table1[m];
208    let b = lsp_pow_m_table2[m];
209    lsp_pow_e_table[e] * (a + b * t)
210}
211
212fn wma_lsp_to_curve_tables(
213    out: &mut [f32],
214    n: usize,
215    lsp: &[f32; NB_LSP_COEFS],
216    lsp_cos_table: &[f32],
217    lsp_pow_e_table: &[f32; 256],
218    lsp_pow_m_table1: &[f32; 1 << LSP_POW_BITS],
219    lsp_pow_m_table2: &[f32; 1 << LSP_POW_BITS],
220) -> f32 {
221    // Direct translation of `wma_lsp_to_curve` from upstream wmadec.c, parameterized to avoid borrowing `self`.
222    let mut val_max = 0.0f32;
223    for i in 0..n {
224        let mut p = 0.5f32;
225        let mut q = 0.5f32;
226        let w = lsp_cos_table[i];
227        let mut j = 1usize;
228        while j < NB_LSP_COEFS {
229            q *= w - lsp[j - 1];
230            p *= w - lsp[j];
231            j += 2;
232        }
233        p *= p * (2.0f32 - w);
234        q *= q * (2.0f32 + w);
235        let mut v = p + q;
236        v = pow_m1_4_tables(v, lsp_pow_e_table, lsp_pow_m_table1, lsp_pow_m_table2);
237        if v > val_max {
238            val_max = v;
239        }
240        out[i] = v;
241    }
242    val_max
243}
244
245fn wma_window_apply(
246    out: &mut [f32],
247    output: &[f32],
248    windows: &[Vec<f32>],
249    frame_len_bits: i32,
250    block_len_bits: i32,
251    prev_block_len_bits: i32,
252    next_block_len_bits: i32,
253    block_len: usize,
254) {
255    // Direct translation of upstream `wma_window`, but parameterized to avoid borrowing `self`.
256    let mut in_buf: &[f32] = output;
257
258    // Left part.
259    if block_len_bits <= prev_block_len_bits {
260        let bsize = (frame_len_bits - block_len_bits) as usize;
261        let win = &windows[bsize];
262        for i in 0..block_len {
263            out[i] += in_buf[i] * win[i];
264        }
265    } else {
266        let prev_len = 1usize << prev_block_len_bits;
267        let n = (block_len - prev_len) / 2;
268        let bsize = (frame_len_bits - prev_block_len_bits) as usize;
269        let win = &windows[bsize];
270        for i in 0..prev_len {
271            let idx = n + i;
272            out[idx] += in_buf[idx] * win[i];
273        }
274        out[n + prev_len..n + prev_len + n]
275            .copy_from_slice(&in_buf[n + prev_len..n + prev_len + n]);
276    }
277
278    // Right part.
279    let out2 = &mut out[block_len..];
280    in_buf = &in_buf[block_len..];
281
282    if block_len_bits <= next_block_len_bits {
283        let bsize = (frame_len_bits - block_len_bits) as usize;
284        vector_fmul_reverse(
285            &mut out2[..block_len],
286            &in_buf[..block_len],
287            &windows[bsize],
288        );
289    } else {
290        let next_len = 1usize << next_block_len_bits;
291        let n = (block_len - next_len) / 2;
292        let bsize = (frame_len_bits - next_block_len_bits) as usize;
293
294        // FFmpeg wma_window(): when the following block is shorter, the
295        // right half consists of an unwindowed prefix, the short falling
296        // window, then zero padding.  Copying the *tail* here (the old port)
297        // carries stale MDCT samples into the overlap-add region and produces
298        // a click/stutter exactly at long -> short block transitions.
299        out2[..n].copy_from_slice(&in_buf[..n]);
300        vector_fmul_reverse(
301            &mut out2[n..n + next_len],
302            &in_buf[n..n + next_len],
303            &windows[bsize],
304        );
305        out2[n + next_len..n + next_len + n].fill(0.0);
306    }
307}
308
309impl WmaDecoder {
310    pub fn new(info: &AudioStreamInfo) -> Result<Self> {
311        let version = match info.format_tag {
312            0x0160 => WmaVersion::V1,
313            0x0161 => WmaVersion::V2,
314            _ => {
315                return Err(DecoderError::Unsupported(format!(
316                    "unsupported WMA format tag: 0x{:04x}",
317                    info.format_tag
318                )));
319            }
320        };
321
322        if info.block_align == 0 {
323            return Err(DecoderError::InvalidData("block_align is not set".into()));
324        }
325
326        let channels = info.channels as usize;
327        if channels == 0 || channels > MAX_CHANNELS {
328            return Err(DecoderError::Unsupported(
329                "only mono/stereo supported".into(),
330            ));
331        }
332
333        // Extract flags2 like upstream.
334        let mut flags2: u16 = 0;
335        let extradata = &info.extra_data;
336        match version {
337            WmaVersion::V1 => {
338                if extradata.len() >= 4 {
339                    flags2 = u16::from_le_bytes([extradata[2], extradata[3]]);
340                }
341            }
342            WmaVersion::V2 => {
343                if extradata.len() >= 6 {
344                    flags2 = u16::from_le_bytes([extradata[4], extradata[5]]);
345                }
346            }
347        }
348
349        let mut use_variable_block_len = (flags2 & 0x0004) != 0;
350        let use_exp_vlc = (flags2 & 0x0001) != 0;
351        let use_bit_reservoir = (flags2 & 0x0002) != 0;
352
353        // upstream quirk (issue1503).
354        if let WmaVersion::V2 = version
355            && extradata.len() >= 8
356        {
357            let v = u16::from_le_bytes([extradata[4], extradata[5]]);
358            if v == 0x000d && use_variable_block_len {
359                use_variable_block_len = false;
360            }
361        }
362
363        // Pre-init fixed fields.
364        let mut dec = Self {
365            version,
366            channels,
367            sample_rate: info.sample_rate,
368            bit_rate: info.bit_rate,
369            block_align: info.block_align,
370
371            use_exp_vlc,
372            use_bit_reservoir,
373            use_variable_block_len,
374            use_noise_coding: true,
375
376            byte_offset_bits: 0,
377
378            exp_vlc: Vlc::default(),
379            hgain_vlc: Vlc::default(),
380            coef_vlc: [Vlc::default(), Vlc::default()],
381            run_table: [Vec::new(), Vec::new()],
382            level_table: [Vec::new(), Vec::new()],
383
384            frame_len_bits: 0,
385            frame_len: 0,
386            nb_block_sizes: 0,
387
388            reset_block_lengths: true,
389            block_len_bits: 0,
390            next_block_len_bits: 0,
391            prev_block_len_bits: 0,
392            block_len: 0,
393            block_num: 0,
394            block_pos: 0,
395
396            ms_stereo: false,
397            channel_coded: [false; MAX_CHANNELS],
398
399            exponent_sizes: [0usize; BLOCK_NB_SIZES],
400            exponent_bands: [[0u16; 25]; BLOCK_NB_SIZES],
401            high_band_start: [0usize; BLOCK_NB_SIZES],
402            coefs_start: 0,
403            coefs_end: [0usize; BLOCK_NB_SIZES],
404            exponent_high_sizes: [0usize; BLOCK_NB_SIZES],
405            exponent_high_bands: [[0u16; HIGH_BAND_MAX_SIZE]; BLOCK_NB_SIZES],
406
407            high_band_coded: [[false; HIGH_BAND_MAX_SIZE]; MAX_CHANNELS],
408            high_band_values: [[0i32; HIGH_BAND_MAX_SIZE]; MAX_CHANNELS],
409
410            exponents_bsize: [0usize; MAX_CHANNELS],
411            exponents: [vec![0f32; BLOCK_MAX_SIZE], vec![0f32; BLOCK_MAX_SIZE]],
412            max_exponent: [1.0f32; MAX_CHANNELS],
413            coefs1: [vec![0f32; BLOCK_MAX_SIZE], vec![0f32; BLOCK_MAX_SIZE]],
414            coefs: [vec![0f32; BLOCK_MAX_SIZE], vec![0f32; BLOCK_MAX_SIZE]],
415
416            mdct: Vec::new(),
417            windows: Vec::new(),
418            output: vec![0f32; BLOCK_MAX_SIZE * 2],
419            frame_out: [
420                vec![0f32; BLOCK_MAX_SIZE * 2],
421                vec![0f32; BLOCK_MAX_SIZE * 2],
422            ],
423
424            last_superframe: vec![0u8; MAX_CODED_SUPERFRAME_SIZE + 64],
425            last_bitoffset: 0,
426            last_superframe_len: 0,
427            pending_packet_bytes: Vec::new(),
428            pending_packet_pts_ms: None,
429            eof_done: false,
430
431            noise_table: vec![0f32; NOISE_TAB_SIZE],
432            noise_index: 0,
433            noise_mult: 0.0,
434
435            lsp_cos_table: vec![0f32; BLOCK_MAX_SIZE],
436            lsp_pow_e_table: [0f32; 256],
437            lsp_pow_m_table1: [0f32; 1 << LSP_POW_BITS],
438            lsp_pow_m_table2: [0f32; 1 << LSP_POW_BITS],
439
440            exponents_initialized: [false; MAX_CHANNELS],
441        };
442
443        // Full init = ff_wma_init + wma_decode_init bits.
444        dec.ff_wma_init(flags2 as i32)?;
445        dec.wma_decode_init(flags2 as i32)?;
446
447        Ok(dec)
448    }
449
450    pub fn sample_rate(&self) -> u32 {
451        self.sample_rate
452    }
453
454    pub fn channels(&self) -> u16 {
455        self.channels as u16
456    }
457
458    pub fn frame_len(&self) -> usize {
459        self.frame_len
460    }
461
462    /// Decode one assembled ASF audio media object.
463    ///
464    /// ASF demuxing returns complete media objects, while WMAv1/v2 decoding is
465    /// defined on fixed `block_align` codec packets. A media object may contain
466    /// several codec packets (and a codec packet may be completed by bytes from
467    /// the next object), so packetize the byte stream here exactly once before
468    /// entering the FFmpeg-derived superframe decoder.
469    pub fn decode_packet(&mut self, pkt: &[u8], pts_ms: u32) -> Result<Option<PcmFrameF32>> {
470        if pkt.is_empty() {
471            return self.flush(pts_ms);
472        }
473
474        if self.eof_done {
475            return Err(DecoderError::InvalidData(
476                "WMAv1/2 data supplied after decoder flush".into(),
477            ));
478        }
479
480        if self.pending_packet_bytes.is_empty() {
481            self.pending_packet_pts_ms = Some(pts_ms);
482        }
483        self.pending_packet_bytes.extend_from_slice(pkt);
484
485        let output_pts_ms = self.pending_packet_pts_ms.unwrap_or(pts_ms);
486        let block_align = self.block_align as usize;
487        let mut output = Vec::new();
488
489        while self.pending_packet_bytes.len() >= block_align {
490            // Use split_off instead of drain so large ASF media objects do not
491            // repeatedly shift the remaining compressed data.
492            let rest = self.pending_packet_bytes.split_off(block_align);
493            let block = std::mem::replace(&mut self.pending_packet_bytes, rest);
494
495            if let Some(frame) = self.decode_codec_packet(&block, output_pts_ms)? {
496                output.extend_from_slice(&frame.samples);
497            }
498
499            if self.pending_packet_bytes.is_empty() {
500                self.pending_packet_pts_ms = None;
501            }
502        }
503
504        if output.is_empty() {
505            Ok(None)
506        } else {
507            Ok(Some(PcmFrameF32 {
508                pts_ms: output_pts_ms,
509                sample_rate: self.sample_rate,
510                channels: self.channels as u16,
511                samples: output,
512            }))
513        }
514    }
515
516    fn flush(&mut self, pts_ms: u32) -> Result<Option<PcmFrameF32>> {
517        if self.eof_done {
518            return Ok(None);
519        }
520        self.eof_done = true;
521
522        // A complete ASF stream should end on a WMAv1/v2 block_align boundary.
523        // Do not attempt to decode a short tail as a packet: doing so destroys
524        // bit-reservoir state and was one source of misleading frame errors.
525        self.pending_packet_bytes.clear();
526        self.pending_packet_pts_ms = None;
527
528        // Match wmadec's delayed overlap output at EOF.
529        let mut out = Vec::with_capacity(self.frame_len * self.channels);
530        for i in 0..self.frame_len {
531            for ch in 0..self.channels {
532                out.push(self.frame_out[ch][i]);
533            }
534        }
535        self.last_superframe_len = 0;
536        Ok(Some(PcmFrameF32 {
537            pts_ms,
538            sample_rate: self.sample_rate,
539            channels: self.channels as u16,
540            samples: out,
541        }))
542    }
543
544    /// Decode exactly one WMAv1/v2 `block_align` codec packet.
545    fn decode_codec_packet(&mut self, buf: &[u8], pts_ms: u32) -> Result<Option<PcmFrameF32>> {
546        debug_assert_eq!(buf.len(), self.block_align as usize);
547
548        let mut gb = GetBitContext::new(buf);
549
550        let mut nb_frames: i32;
551
552        if self.use_bit_reservoir {
553            // super frame header
554            gb.skip_bits(4)?; // super frame index
555            let mut nf = gb.get_bits(4)? as i32;
556            nf -= if self.last_superframe_len == 0 { 1 } else { 0 };
557            nb_frames = nf;
558            if nb_frames <= 0 {
559                let is_error = nb_frames < 0 || gb.bits_left() <= 8;
560                if is_error {
561                    return Err(DecoderError::InvalidData(format!(
562                        "nb_frames is {nb_frames} bits left {}",
563                        gb.bits_left()
564                    )));
565                }
566
567                if self.last_superframe_len + buf.len() - 1 > MAX_CODED_SUPERFRAME_SIZE {
568                    return Err(DecoderError::InvalidData("bit reservoir overflow".into()));
569                }
570
571                let mut q = self.last_superframe_len;
572                let mut len = buf.len() - 1;
573                while len > 0 {
574                    let b = gb.get_bits(8)? as u8;
575                    self.last_superframe[q] = b;
576                    q += 1;
577                    len -= 1;
578                }
579
580                self.last_superframe_len += 8 * buf.len() - 8;
581                return Ok(None);
582            }
583        } else {
584            nb_frames = 1;
585        }
586
587        // Planar output like upstream, then interleave.
588        let mut samples: [Vec<f32>; MAX_CHANNELS] = [Vec::new(), Vec::new()];
589        for ch in 0..self.channels {
590            samples[ch].resize(nb_frames as usize * self.frame_len, 0f32);
591        }
592        let mut samples_offset: usize = 0;
593
594        if self.use_bit_reservoir {
595            let bit_offset = gb.get_bits((self.byte_offset_bits + 3) as usize)? as usize;
596            if bit_offset as isize > gb.bits_left() {
597                return Err(DecoderError::InvalidData(
598                    "Invalid last frame bit offset".into(),
599                ));
600            }
601
602            if self.last_superframe_len > 0 {
603                // Add `bit_offset` bits to last frame.
604                let add_bytes = (bit_offset + 7) >> 3;
605                if self.last_superframe_len + add_bytes > MAX_CODED_SUPERFRAME_SIZE {
606                    return Err(DecoderError::InvalidData("bit reservoir overflow".into()));
607                }
608
609                let mut q = self.last_superframe_len;
610                let mut len = bit_offset;
611                while len > 7 {
612                    self.last_superframe[q] = gb.get_bits(8)? as u8;
613                    q += 1;
614                    len -= 8;
615                }
616                if len > 0 {
617                    self.last_superframe[q] = (gb.get_bits(len)? as u8) << (8 - len);
618                }
619
620                // Decode the previous frame.
621                let total_bits = self.last_superframe_len * 8 + bit_offset;
622                let need_bytes = total_bits.div_ceil(8);
623                // Avoid borrowing `self` across the decode call.
624                let sf_bytes: Vec<u8> = self.last_superframe[..need_bytes].to_vec();
625                // FFmpeg initializes this reservoir reader with the exact bit
626                // length, not the rounded-up byte length.  GetBitContext still
627                // provides its normal eight zero-padding bits for look-ahead.
628                let mut gb2 = GetBitContext::new_bits(&sf_bytes, total_bits)?;
629                if self.last_bitoffset > 0 {
630                    gb2.skip_bits(self.last_bitoffset)?;
631                }
632                // Do not reset the variable-block-length state here.  This is
633                // the frame that started at the end of the previous codec
634                // packet, and WMA carries prev/current/next block lengths
635                // across that packet boundary.  FFmpeg's wmadec deliberately
636                // only resets before the first wholly-new frame below.
637                self.wma_decode_frame(&mut gb2, &mut samples, samples_offset)?;
638                samples_offset += self.frame_len;
639                nb_frames -= 1;
640            }
641
642            // Read each frame starting from bit_offset.
643            let pos = bit_offset + 4 + 4 + (self.byte_offset_bits as usize) + 3;
644            if pos >= MAX_CODED_SUPERFRAME_SIZE * 8 || pos > buf.len() * 8 {
645                return Err(DecoderError::InvalidData("invalid superframe pos".into()));
646            }
647
648            let start_byte = pos >> 3;
649            let mut gb3 = GetBitContext::new(&buf[start_byte..]);
650            let rem = pos & 7;
651            if rem > 0 {
652                gb3.skip_bits(rem)?;
653            }
654
655            self.reset_block_lengths = true;
656            for _ in 0..nb_frames {
657                self.wma_decode_frame(&mut gb3, &mut samples, samples_offset)?;
658                samples_offset += self.frame_len;
659            }
660
661            // Copy end of frame into last frame buffer.
662            let consumed_bits = gb3.bits_read();
663            let mut pos2 =
664                consumed_bits + ((bit_offset + 4 + 4 + (self.byte_offset_bits as usize) + 3) & !7);
665            self.last_bitoffset = pos2 & 7;
666            pos2 >>= 3;
667            let len = buf.len().saturating_sub(pos2);
668            if len > MAX_CODED_SUPERFRAME_SIZE {
669                return Err(DecoderError::InvalidData("invalid reservoir len".into()));
670            }
671            self.last_superframe_len = len;
672            self.last_superframe[..len].copy_from_slice(&buf[pos2..pos2 + len]);
673        } else {
674            // With no bit reservoir there is no superframe boundary at which
675            // FFmpeg resets variable block lengths.  Keep the rolling
676            // prev/current/next state between codec packets.  The initial
677            // decoder state is already reset by ff_wma_init().
678            self.wma_decode_frame(&mut gb, &mut samples, samples_offset)?;
679            samples_offset += self.frame_len;
680        }
681
682        // Interleave.
683        let total_samples = samples_offset * self.channels;
684        let mut out = Vec::with_capacity(total_samples);
685        for i in 0..samples_offset {
686            for ch in 0..self.channels {
687                out.push(samples[ch][i]);
688            }
689        }
690
691        Ok(Some(PcmFrameF32 {
692            pts_ms,
693            sample_rate: self.sample_rate,
694            channels: self.channels as u16,
695            samples: out,
696        }))
697    }
698
699    fn wma_decode_init(&mut self, flags2: i32) -> Result<()> {
700        // Initialize inverse MDCT plans for each WMA block size.
701        let scale = 1.0f64 / 32768.0f64;
702        self.mdct.clear();
703        for i in 0..self.nb_block_sizes {
704            let len = 1usize << (self.frame_len_bits - i as i32);
705            self.mdct.push(MdctNaive::new(len, scale));
706        }
707
708        // Noise/hgain VLC.
709        if self.use_noise_coding {
710            let flat: &[u8] = unsafe {
711                std::slice::from_raw_parts(
712                    tables::FF_WMA_HGAIN_HUFFTAB.as_ptr() as *const u8,
713                    tables::FF_WMA_HGAIN_HUFFTAB.len() * 2,
714                )
715            };
716            let lens: &[i8] = unsafe {
717                std::slice::from_raw_parts(flat.as_ptr().add(1) as *const i8, flat.len() - 1)
718            };
719            ff_vlc_init_from_lengths(
720                &mut self.hgain_vlc,
721                HGAINVLCBITS,
722                tables::FF_WMA_HGAIN_HUFFTAB.len(),
723                lens,
724                2,
725                Some(flat),
726                2,
727                1,
728                -18,
729                0,
730            )?;
731        }
732
733        // Exponent VLC.
734        if self.use_exp_vlc {
735            let bits = &tables::FF_AAC_SCALEFACTOR_BITS;
736            let codes_u32 = &tables::FF_AAC_SCALEFACTOR_CODE;
737            let codes_bytes: &[u8] = unsafe {
738                std::slice::from_raw_parts(codes_u32.as_ptr() as *const u8, codes_u32.len() * 4)
739            };
740
741            ff_vlc_init_sparse(
742                &mut self.exp_vlc,
743                EXPVLCBITS,
744                bits.len(),
745                bits,
746                1,
747                1,
748                codes_bytes,
749                4,
750                4,
751                None,
752                0,
753                0,
754                0,
755            )?;
756        } else {
757            self.wma_lsp_to_curve_init(self.frame_len);
758        }
759
760        // Flags and defaults.
761        let _ = flags2;
762        Ok(())
763    }
764
765    fn ff_wma_init(&mut self, flags2: i32) -> Result<()> {
766        // Validate stream params.
767        if self.sample_rate > 50000 || self.channels > 2 || self.bit_rate == 0 {
768            return Err(DecoderError::InvalidData("invalid audio params".into()));
769        }
770
771        let version_id = self.version.id();
772
773        // Compute MDCT block size.
774        self.frame_len_bits = ff_wma_get_frame_len_bits(self.sample_rate as i32, version_id, 0);
775        self.next_block_len_bits = self.frame_len_bits;
776        self.prev_block_len_bits = self.frame_len_bits;
777        self.block_len_bits = self.frame_len_bits;
778
779        self.frame_len = 1usize << self.frame_len_bits;
780        if self.use_variable_block_len {
781            let mut nb = ((flags2 >> 3) & 3) + 1;
782            if (self.bit_rate / self.channels as u32) >= 32000 {
783                nb += 2;
784            }
785            let nb_max = self.frame_len_bits - BLOCK_MIN_BITS;
786            if nb > nb_max {
787                nb = nb_max;
788            }
789            self.nb_block_sizes = (nb + 1) as usize;
790        } else {
791            self.nb_block_sizes = 1;
792        }
793
794        // Rate dependent params.
795        self.use_noise_coding = true;
796        let mut high_freq = self.sample_rate as f32 * 0.5f32;
797
798        // Version 2 normalized rates.
799        let mut sample_rate1 = self.sample_rate as i32;
800        if version_id == 2 {
801            if sample_rate1 >= 44100 {
802                sample_rate1 = 44100;
803            } else if sample_rate1 >= 22050 {
804                sample_rate1 = 22050;
805            } else if sample_rate1 >= 16000 {
806                sample_rate1 = 16000;
807            } else if sample_rate1 >= 11025 {
808                sample_rate1 = 11025;
809            } else if sample_rate1 >= 8000 {
810                sample_rate1 = 8000;
811            }
812        }
813
814        let bps = (self.bit_rate as f32) / ((self.channels as f32) * (self.sample_rate as f32));
815        let mut bps1 = bps;
816        if self.channels == 2 {
817            bps1 = bps * 1.6f32;
818        }
819
820        let x = (bps * (self.frame_len as f32) / 8.0 + 0.5) as u32;
821        self.byte_offset_bits = ilog2_u32(x.max(1)) + 2;
822
823        // Compute high frequency and noise coding.
824        if sample_rate1 == 44100 {
825            if bps1 >= 0.61 {
826                self.use_noise_coding = false;
827            } else {
828                high_freq *= 0.4;
829            }
830        } else if sample_rate1 == 22050 {
831            if bps1 >= 1.16 {
832                self.use_noise_coding = false;
833            } else if bps1 >= 0.72 {
834                high_freq *= 0.7;
835            } else {
836                high_freq *= 0.6;
837            }
838        } else if sample_rate1 == 16000 {
839            if bps > 0.5 {
840                high_freq *= 0.5;
841            } else {
842                high_freq *= 0.3;
843            }
844        } else if sample_rate1 == 11025 {
845            high_freq *= 0.7;
846        } else if sample_rate1 == 8000 {
847            if bps <= 0.625 {
848                high_freq *= 0.5;
849            } else if bps > 0.75 {
850                self.use_noise_coding = false;
851            } else {
852                high_freq *= 0.65;
853            }
854        } else {
855            if bps >= 0.8 {
856                high_freq *= 0.75;
857            } else if bps >= 0.6 {
858                high_freq *= 0.6;
859            } else {
860                high_freq *= 0.5;
861            }
862        }
863
864        // Compute scale factor band sizes.
865        self.coefs_start = if version_id == 1 { 3 } else { 0 };
866
867        for k in 0..self.nb_block_sizes {
868            let block_len = self.frame_len >> k;
869
870            if version_id == 1 {
871                let mut lpos = 0usize;
872                let mut i = 0usize;
873                for idx in 0..25 {
874                    let a = tables::FF_WMA_CRITICAL_FREQS[idx] as usize;
875                    let b = self.sample_rate as usize;
876                    let mut pos = ((block_len * 2 * a) + (b >> 1)) / b;
877                    if pos > block_len {
878                        pos = block_len;
879                    }
880                    self.exponent_bands[0][idx] = (pos - lpos) as u16;
881                    if pos >= block_len {
882                        i = idx + 1;
883                        break;
884                    }
885                    lpos = pos;
886                    i = idx + 1;
887                }
888                self.exponent_sizes[0] = i;
889            } else {
890                // Hardcoded tables.
891                let a = self.frame_len_bits - BLOCK_MIN_BITS - (k as i32);
892                let mut table_row: Option<&[u8; 25]> = None;
893                if a < 3 {
894                    if self.sample_rate >= 44100 {
895                        table_row = Some(&tables::EXPONENT_BAND_44100[a as usize]);
896                    } else if self.sample_rate >= 32000 {
897                        table_row = Some(&tables::EXPONENT_BAND_32000[a as usize]);
898                    } else if self.sample_rate >= 22050 {
899                        table_row = Some(&tables::EXPONENT_BAND_22050[a as usize]);
900                    }
901                }
902
903                if let Some(row) = table_row {
904                    let n = row[0] as usize;
905                    for i in 0..n {
906                        self.exponent_bands[k][i] = row[1 + i] as u16;
907                    }
908                    self.exponent_sizes[k] = n;
909                } else {
910                    let mut j = 0usize;
911                    let mut lpos = 0usize;
912                    for idx in 0..25 {
913                        let a = tables::FF_WMA_CRITICAL_FREQS[idx] as usize;
914                        let b = self.sample_rate as usize;
915                        let mut pos = ((block_len * 2 * a) + (b << 1)) / (4 * b);
916                        pos <<= 2;
917                        if pos > block_len {
918                            pos = block_len;
919                        }
920                        if pos > lpos {
921                            self.exponent_bands[k][j] = (pos - lpos) as u16;
922                            j += 1;
923                        }
924                        if pos >= block_len {
925                            break;
926                        }
927                        lpos = pos;
928                    }
929                    self.exponent_sizes[k] = j;
930                }
931            }
932
933            self.coefs_end[k] = (self.frame_len - ((self.frame_len * 9) / 100)) >> k;
934            self.high_band_start[k] =
935                (((block_len as f32) * 2.0 * high_freq) / (self.sample_rate as f32) + 0.5) as usize;
936
937            let n = self.exponent_sizes[k];
938            let mut j = 0usize;
939            let mut pos = 0usize;
940            for i in 0..n {
941                let start0 = pos;
942                pos += self.exponent_bands[k][i] as usize;
943                let end0 = pos;
944                let mut start = start0;
945                let mut end = end0;
946                if start < self.high_band_start[k] {
947                    start = self.high_band_start[k];
948                }
949                if end > self.coefs_end[k] {
950                    end = self.coefs_end[k];
951                }
952                if end > start {
953                    self.exponent_high_bands[k][j] = (end - start) as u16;
954                    j += 1;
955                }
956            }
957            self.exponent_high_sizes[k] = j;
958        }
959
960        // Init MDCT windows.
961        self.windows.clear();
962        for i in 0..self.nb_block_sizes {
963            let half = 1usize << (self.frame_len_bits - i as i32);
964            self.windows.push(sine_window_init(half));
965        }
966
967        self.reset_block_lengths = true;
968
969        // Noise table.
970        if self.use_noise_coding {
971            self.noise_mult = if self.use_exp_vlc { 0.02 } else { 0.04 };
972            let mut seed: u32 = 1;
973            let norm = (1.0 / ((1u64 << 31) as f32)) * 3.0f32.sqrt() * self.noise_mult;
974            for i in 0..NOISE_TAB_SIZE {
975                seed = seed.wrapping_mul(314159).wrapping_add(1);
976                self.noise_table[i] = (seed as i32 as f32) * norm;
977            }
978        }
979
980        // Choose coef VLC tables.
981        let mut coef_vlc_table = 2;
982        if self.sample_rate >= 32000 {
983            if bps1 < 0.72 {
984                coef_vlc_table = 0;
985            } else if bps1 < 1.16 {
986                coef_vlc_table = 1;
987            }
988        }
989        let t0 = &tables::COEF_VLCS[coef_vlc_table * 2];
990        let t1 = &tables::COEF_VLCS[coef_vlc_table * 2 + 1];
991
992        self.init_coef_vlc(0, t0)?;
993        self.init_coef_vlc(1, t1)?;
994
995        Ok(())
996    }
997
998    fn init_coef_vlc(&mut self, idx: usize, tbl: &tables::CoefVlcTable) -> Result<()> {
999        // vlc_init(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0)
1000        let bits = tbl.huffbits;
1001        let codes_u32 = tbl.huffcodes;
1002        let codes_bytes: &[u8] = unsafe {
1003            std::slice::from_raw_parts(codes_u32.as_ptr() as *const u8, codes_u32.len() * 4)
1004        };
1005        ff_vlc_init_sparse(
1006            &mut self.coef_vlc[idx],
1007            VLCBITS,
1008            tbl.n,
1009            bits,
1010            1,
1011            1,
1012            codes_bytes,
1013            4,
1014            4,
1015            None,
1016            0,
1017            0,
1018            0,
1019        )?;
1020
1021        // Build run/level tables like init_coef_vlc.
1022        let n = tbl.n;
1023        let levels_table = tbl.levels;
1024
1025        let mut run_table = vec![0u16; n];
1026        let mut flevel_table = vec![0f32; n];
1027        let mut int_table = vec![0u16; n];
1028
1029        let mut i = 2usize;
1030        let mut level = 1usize;
1031        let mut k = 0usize;
1032        while i < n {
1033            int_table[k] = i as u16;
1034            let l = levels_table[k] as usize;
1035            k += 1;
1036            for j in 0..l {
1037                run_table[i] = j as u16;
1038                flevel_table[i] = level as f32;
1039                i += 1;
1040            }
1041            level += 1;
1042        }
1043
1044        self.run_table[idx] = run_table;
1045        self.level_table[idx] = flevel_table;
1046
1047        Ok(())
1048    }
1049
1050    fn ff_wma_total_gain_to_bits(total_gain: i32) -> i32 {
1051        if total_gain < 15 {
1052            13
1053        } else if total_gain < 32 {
1054            12
1055        } else if total_gain < 40 {
1056            11
1057        } else if total_gain < 45 {
1058            10
1059        } else {
1060            9
1061        }
1062    }
1063
1064    fn ff_wma_get_large_val(gb: &mut GetBitContext<'_>) -> Result<u32> {
1065        let mut n_bits: usize = 8;
1066        if gb.get_bits1()? != 0 {
1067            n_bits += 8;
1068            if gb.get_bits1()? != 0 {
1069                n_bits += 8;
1070                if gb.get_bits1()? != 0 {
1071                    n_bits += 7;
1072                }
1073            }
1074        }
1075        gb.get_bits_long(n_bits)
1076    }
1077
1078    #[allow(clippy::too_many_arguments)]
1079    fn ff_wma_run_level_decode(
1080        gb: &mut GetBitContext<'_>,
1081        vlc: &[VlcElem],
1082        level_table: &[f32],
1083        run_table: &[u16],
1084        version: i32,
1085        ptr: &mut [f32],
1086        mut offset: i32,
1087        num_coefs: i32,
1088        block_len: usize,
1089        frame_len_bits: i32,
1090        coef_nb_bits: i32,
1091    ) -> Result<()> {
1092        let coef_mask = (block_len as i32) - 1;
1093        while offset < num_coefs {
1094            let code = get_vlc2(gb, vlc, VLCBITS, VLCMAX)?;
1095            if code > 1 {
1096                offset += run_table[code as usize] as i32;
1097                let sign = gb.get_bits1()? as i32 - 1;
1098                let lvl_bits = level_table[code as usize].to_bits();
1099                let signed_bits = lvl_bits ^ ((sign as u32) & 0x8000_0000);
1100                ptr[(offset & coef_mask) as usize] = f32::from_bits(signed_bits);
1101            } else if code == 1 {
1102                break;
1103            } else {
1104                let level: i32;
1105                if version == 0 {
1106                    level = gb.get_bits(coef_nb_bits as usize)? as i32;
1107                    offset += gb.get_bits(frame_len_bits as usize)? as i32;
1108                } else {
1109                    level = Self::ff_wma_get_large_val(gb)? as i32;
1110                    if gb.get_bits1()? != 0 {
1111                        if gb.get_bits1()? != 0 {
1112                            if gb.get_bits1()? != 0 {
1113                                return Err(DecoderError::InvalidData(
1114                                    "broken escape sequence".into(),
1115                                ));
1116                            } else {
1117                                offset += gb.get_bits(frame_len_bits as usize)? as i32 + 4;
1118                            }
1119                        } else {
1120                            offset += gb.get_bits(2)? as i32 + 1;
1121                        }
1122                    }
1123                }
1124                let sign = gb.get_bits1()? as i32 - 1;
1125                let v = (level ^ sign) - sign;
1126                ptr[(offset & coef_mask) as usize] = v as f32;
1127            }
1128            offset += 1;
1129        }
1130
1131        if offset > num_coefs {
1132            return Err(DecoderError::InvalidData("overflow in spectral RLE".into()));
1133        }
1134
1135        Ok(())
1136    }
1137
1138    fn wma_lsp_to_curve_init(&mut self, frame_len: usize) {
1139        let wdel = std::f32::consts::PI / (frame_len as f32);
1140        for i in 0..frame_len {
1141            self.lsp_cos_table[i] = 2.0f32 * (wdel * (i as f32)).cos();
1142        }
1143
1144        for i in 0..256 {
1145            let e = (i as i32) - 126;
1146            self.lsp_pow_e_table[i] = (e as f32 * -0.25).exp2();
1147        }
1148
1149        let mut b = 1.0f32;
1150        for i in (0..(1 << LSP_POW_BITS)).rev() {
1151            let m = (1 << LSP_POW_BITS) + i;
1152            let mut a = (m as f32) * (0.5f32 / (1 << LSP_POW_BITS) as f32);
1153            a = 1.0f32 / a.sqrt().sqrt();
1154            self.lsp_pow_m_table1[i] = 2.0f32 * a - b;
1155            self.lsp_pow_m_table2[i] = b - a;
1156            b = a;
1157        }
1158    }
1159
1160    fn decode_exp_lsp(&mut self, gb: &mut GetBitContext<'_>, ch: usize) -> Result<()> {
1161        // upstream wmadec.c: decode_exp_lsp()
1162        let mut lsp: [f32; NB_LSP_COEFS] = [0.0; NB_LSP_COEFS];
1163        for i in 0..NB_LSP_COEFS {
1164            let val = if i == 0 || i >= 8 {
1165                gb.get_bits(3)? as usize
1166            } else {
1167                gb.get_bits(4)? as usize
1168            };
1169            lsp[i] = tables::FF_WMA_LSP_CODEBOOK[i][val];
1170        }
1171
1172        let cos = &self.lsp_cos_table;
1173        let e = &self.lsp_pow_e_table;
1174        let m1 = &self.lsp_pow_m_table1;
1175        let m2 = &self.lsp_pow_m_table2;
1176        let out = &mut self.exponents[ch];
1177        let vmax = wma_lsp_to_curve_tables(out, self.block_len, &lsp, cos, e, m1, m2);
1178        self.max_exponent[ch] = vmax;
1179        Ok(())
1180    }
1181
1182    fn decode_exp_vlc(&mut self, gb: &mut GetBitContext<'_>, ch: usize) -> Result<()> {
1183        let mut last_exp: i32;
1184        let mut max_scale: f32 = 0.0;
1185        let ptab = &tables::POW_TAB[60..];
1186
1187        let bsize = (self.frame_len_bits - self.block_len_bits) as usize;
1188        let bands = &self.exponent_bands[bsize];
1189
1190        let mut q = 0usize;
1191        let q_end = self.block_len;
1192
1193        if self.version.id() == 1 {
1194            last_exp = gb.get_bits(5)? as i32 + 10;
1195            let v = ptab[last_exp as usize];
1196            max_scale = v;
1197            let n = bands[0] as usize;
1198            for _ in 0..n {
1199                self.exponents[ch][q] = v;
1200                q += 1;
1201            }
1202        } else {
1203            last_exp = 36;
1204        }
1205
1206        let mut ptr_idx = 0usize;
1207        if self.version.id() == 1 {
1208            ptr_idx = 1;
1209        }
1210
1211        while q < q_end {
1212            let code = get_vlc2(gb, &self.exp_vlc.table, EXPVLCBITS, EXPMAX)?;
1213            last_exp += code - 60;
1214            let pow_idx = exponent_pow_tab_index(last_exp).ok_or_else(|| {
1215                DecoderError::InvalidData(format!("Exponent out of range: {last_exp}"))
1216            })?;
1217            let v = tables::POW_TAB[pow_idx];
1218            if v > max_scale {
1219                max_scale = v;
1220            }
1221
1222            // Upstream's ptr++ is safe because the exponent-band tables are
1223            // fixed codec tables whose sizes sum exactly to block_len.  Keep
1224            // the Rust port fail-closed instead of panicking if a future table
1225            // translation ever violates that invariant again.
1226            if ptr_idx >= self.exponent_sizes[bsize] {
1227                return Err(DecoderError::InvalidData(format!(
1228                    "exponent band table exhausted: bsize={bsize} block_len={} q={q} bands={}",
1229                    self.block_len, self.exponent_sizes[bsize]
1230                )));
1231            }
1232            let n = bands[ptr_idx] as usize;
1233            ptr_idx += 1;
1234            if q + n > q_end {
1235                return Err(DecoderError::InvalidData(format!(
1236                    "exponent band table overrun: bsize={bsize} block_len={} q={q} band={n}",
1237                    self.block_len
1238                )));
1239            }
1240            for _ in 0..n {
1241                self.exponents[ch][q] = v;
1242                q += 1;
1243            }
1244        }
1245
1246        self.max_exponent[ch] = max_scale;
1247        Ok(())
1248    }
1249
1250    fn wma_decode_block(&mut self, gb: &mut GetBitContext<'_>) -> Result<bool> {
1251        // Returns Ok(true) if last block of frame.
1252        // Translated from wma_decode_block.
1253
1254        // Compute current block length.
1255        if self.use_variable_block_len {
1256            let n = ilog2_u32((self.nb_block_sizes - 1) as u32) + 1;
1257            if self.reset_block_lengths {
1258                self.reset_block_lengths = false;
1259                let v = gb.get_bits(n as usize)? as usize;
1260                if v >= self.nb_block_sizes {
1261                    return Err(DecoderError::InvalidData(
1262                        "prev_block_len_bits out of range".into(),
1263                    ));
1264                }
1265                self.prev_block_len_bits = self.frame_len_bits - v as i32;
1266                let v = gb.get_bits(n as usize)? as usize;
1267                if v >= self.nb_block_sizes {
1268                    return Err(DecoderError::InvalidData(
1269                        "block_len_bits out of range".into(),
1270                    ));
1271                }
1272                self.block_len_bits = self.frame_len_bits - v as i32;
1273            } else {
1274                self.prev_block_len_bits = self.block_len_bits;
1275                self.block_len_bits = self.next_block_len_bits;
1276            }
1277            let v = gb.get_bits(n as usize)? as usize;
1278            if v >= self.nb_block_sizes {
1279                return Err(DecoderError::InvalidData(
1280                    "next_block_len_bits out of range".into(),
1281                ));
1282            }
1283            self.next_block_len_bits = self.frame_len_bits - v as i32;
1284        } else {
1285            self.next_block_len_bits = self.frame_len_bits;
1286            self.prev_block_len_bits = self.frame_len_bits;
1287            self.block_len_bits = self.frame_len_bits;
1288        }
1289
1290        let bsize = (self.frame_len_bits - self.block_len_bits) as usize;
1291        if (self.frame_len_bits - self.block_len_bits) as usize >= self.nb_block_sizes {
1292            return Err(DecoderError::InvalidData(
1293                "block_len_bits not initialized".into(),
1294            ));
1295        }
1296
1297        self.block_len = 1usize << self.block_len_bits;
1298        if self.block_pos + self.block_len > self.frame_len {
1299            return Err(DecoderError::InvalidData(format!(
1300                "frame_len overflow: block_pos={} block_len={} frame_len={} prev_bits={} block_bits={} next_bits={}",
1301                self.block_pos,
1302                self.block_len,
1303                self.frame_len,
1304                self.prev_block_len_bits,
1305                self.block_len_bits,
1306                self.next_block_len_bits,
1307            )));
1308        }
1309
1310        if self.channels == 2 {
1311            self.ms_stereo = gb.get_bits1()? != 0;
1312        }
1313
1314        let mut v_any = false;
1315        for ch in 0..self.channels {
1316            let a = gb.get_bits1()? != 0;
1317            self.channel_coded[ch] = a;
1318            v_any |= a;
1319        }
1320
1321        if !v_any {
1322            return self.wma_decode_block_next(gb, bsize);
1323        }
1324
1325        // Total gain.
1326        let mut total_gain: i32 = 1;
1327        loop {
1328            if gb.bits_left() < 7 {
1329                return Err(DecoderError::InvalidData("total_gain overread".into()));
1330            }
1331            let a = gb.get_bits(7)? as i32;
1332            total_gain += a;
1333            if a != 127 {
1334                break;
1335            }
1336        }
1337
1338        let coef_nb_bits = Self::ff_wma_total_gain_to_bits(total_gain);
1339
1340        // Number of coefficients.
1341        let ncoefs = (self.coefs_end[bsize] as i32) - (self.coefs_start as i32);
1342        let mut nb_coefs = [0i32; MAX_CHANNELS];
1343        for ch in 0..self.channels {
1344            nb_coefs[ch] = ncoefs;
1345        }
1346
1347        // Noise coding.
1348        if self.use_noise_coding {
1349            for ch in 0..self.channels {
1350                if self.channel_coded[ch] {
1351                    let n1 = self.exponent_high_sizes[bsize];
1352                    for i in 0..n1 {
1353                        let a = gb.get_bits1()? != 0;
1354                        self.high_band_coded[ch][i] = a;
1355                        if a {
1356                            nb_coefs[ch] -= self.exponent_high_bands[bsize][i] as i32;
1357                        }
1358                    }
1359                }
1360            }
1361            for ch in 0..self.channels {
1362                if self.channel_coded[ch] {
1363                    let n1 = self.exponent_high_sizes[bsize];
1364                    let mut val: i32 = 0x8000_0000u32 as i32;
1365                    for i in 0..n1 {
1366                        if self.high_band_coded[ch][i] {
1367                            if val == (0x8000_0000u32 as i32) {
1368                                val = gb.get_bits(7)? as i32 - 19;
1369                            } else {
1370                                val += get_vlc2(gb, &self.hgain_vlc.table, HGAINVLCBITS, HGAINMAX)?;
1371                            }
1372                            self.high_band_values[ch][i] = val;
1373                        }
1374                    }
1375                }
1376            }
1377        }
1378
1379        // Exponents can be reused in short blocks.
1380        let reuse = (self.block_len_bits == self.frame_len_bits) || (gb.get_bits1()? != 0);
1381        if reuse {
1382            for ch in 0..self.channels {
1383                if self.channel_coded[ch] {
1384                    if self.use_exp_vlc {
1385                        self.decode_exp_vlc(gb, ch)?;
1386                    } else {
1387                        self.decode_exp_lsp(gb, ch)?;
1388                    }
1389                    self.exponents_bsize[ch] = bsize;
1390                    self.exponents_initialized[ch] = true;
1391                }
1392            }
1393        }
1394
1395        for ch in 0..self.channels {
1396            if self.channel_coded[ch] && !self.exponents_initialized[ch] {
1397                return Err(DecoderError::InvalidData(
1398                    "exponents not initialized".into(),
1399                ));
1400            }
1401        }
1402
1403        // Parse spectral coefficients.
1404        for ch in 0..self.channels {
1405            if self.channel_coded[ch] {
1406                let tindex = (ch == 1 && self.ms_stereo) as usize;
1407                for v in &mut self.coefs1[ch][..self.block_len] {
1408                    *v = 0.0;
1409                }
1410                // Decode into coefs1 (upstream WMACoef).
1411                Self::ff_wma_run_level_decode(
1412                    gb,
1413                    &self.coef_vlc[tindex].table,
1414                    &self.level_table[tindex],
1415                    &self.run_table[tindex],
1416                    0,
1417                    &mut self.coefs1[ch],
1418                    0,
1419                    nb_coefs[ch],
1420                    self.block_len,
1421                    self.frame_len_bits,
1422                    coef_nb_bits,
1423                )?;
1424            }
1425            if self.version.id() == 1 && self.channels >= 2 {
1426                gb.align_to_byte();
1427            }
1428        }
1429
1430        // Normalize.
1431        let n4 = self.block_len / 2;
1432        let mut mdct_norm = 1.0f32 / (n4 as f32);
1433        if self.version.id() == 1 {
1434            mdct_norm *= (n4 as f32).sqrt();
1435        }
1436
1437        // Compute MDCT coefficients.
1438        for ch in 0..self.channels {
1439            if !self.channel_coded[ch] {
1440                continue;
1441            }
1442
1443            let esize = self.exponents_bsize[ch];
1444            let mult = ff_exp10f(total_gain as f32 * 0.05f32) / self.max_exponent[ch] * mdct_norm;
1445
1446            let mut coefs_pos = 0usize;
1447
1448            if self.use_noise_coding {
1449                // very low freqs: noise
1450                for i in 0..self.coefs_start {
1451                    let exp_idx = (i << bsize) >> esize;
1452                    let noise = self.noise_table[self.noise_index];
1453                    self.noise_index = (self.noise_index + 1) & (NOISE_TAB_SIZE - 1);
1454                    self.coefs[ch][coefs_pos] = noise * self.exponents[ch][exp_idx] * mult;
1455                    coefs_pos += 1;
1456                }
1457
1458                let n1 = self.exponent_high_sizes[bsize];
1459
1460                // compute power of high bands
1461                let mut exp_power = [0f32; HIGH_BAND_MAX_SIZE];
1462                let mut exponents_ptr = (self.high_band_start[bsize] << bsize) >> esize;
1463                let mut last_high_band: usize = 0;
1464                for j in 0..n1 {
1465                    let n = self.exponent_high_bands[bsize][j] as usize;
1466                    if self.high_band_coded[ch][j] {
1467                        let mut e2: f32 = 0.0;
1468                        for i in 0..n {
1469                            let v = self.exponents[ch][exponents_ptr + ((i << bsize) >> esize)];
1470                            e2 += v * v;
1471                        }
1472                        exp_power[j] = e2 / (n as f32);
1473                        last_high_band = j;
1474                    }
1475                    exponents_ptr += (n << bsize) >> esize;
1476                }
1477
1478                // main freqs and high freqs
1479                let mut exponents_ptr = (self.coefs_start << bsize) >> esize;
1480                let mut coef1_idx = 0usize;
1481
1482                for j in (-1i32)..(n1 as i32) {
1483                    let n = if j < 0 {
1484                        self.high_band_start[bsize].saturating_sub(self.coefs_start)
1485                    } else {
1486                        self.exponent_high_bands[bsize][j as usize] as usize
1487                    };
1488
1489                    if j >= 0 && self.high_band_coded[ch][j as usize] {
1490                        let mut mult1 = (exp_power[j as usize] / exp_power[last_high_band]).sqrt();
1491                        mult1 *= ff_exp10f(self.high_band_values[ch][j as usize] as f32 * 0.05f32);
1492                        mult1 /= self.max_exponent[ch] * self.noise_mult;
1493                        mult1 *= mdct_norm;
1494
1495                        for i in 0..n {
1496                            let noise = self.noise_table[self.noise_index];
1497                            self.noise_index = (self.noise_index + 1) & (NOISE_TAB_SIZE - 1);
1498                            let exp = self.exponents[ch][exponents_ptr + ((i << bsize) >> esize)];
1499                            self.coefs[ch][coefs_pos] = noise * exp * mult1;
1500                            coefs_pos += 1;
1501                        }
1502                        exponents_ptr += (n << bsize) >> esize;
1503                    } else {
1504                        for i in 0..n {
1505                            let noise = self.noise_table[self.noise_index];
1506                            self.noise_index = (self.noise_index + 1) & (NOISE_TAB_SIZE - 1);
1507                            let exp = self.exponents[ch][exponents_ptr + ((i << bsize) >> esize)];
1508                            let coef1 = self.coefs1[ch][coef1_idx];
1509                            coef1_idx += 1;
1510                            self.coefs[ch][coefs_pos] = (coef1 + noise) * exp * mult;
1511                            coefs_pos += 1;
1512                        }
1513                        exponents_ptr += (n << bsize) >> esize;
1514                    }
1515                }
1516
1517                // very high freqs: noise
1518                let n = self.block_len - self.coefs_end[bsize];
1519                let exp_last =
1520                    self.exponents[ch][((exponents_ptr as i32 - (1 << bsize)) >> esize) as usize];
1521                let mult1 = mult * exp_last;
1522                for _ in 0..n {
1523                    let noise = self.noise_table[self.noise_index];
1524                    self.noise_index = (self.noise_index + 1) & (NOISE_TAB_SIZE - 1);
1525                    self.coefs[ch][coefs_pos] = noise * mult1;
1526                    coefs_pos += 1;
1527                }
1528            } else {
1529                for _ in 0..self.coefs_start {
1530                    self.coefs[ch][coefs_pos] = 0.0;
1531                    coefs_pos += 1;
1532                }
1533
1534                let n = nb_coefs[ch] as usize;
1535                for i in 0..n {
1536                    let exp = self.exponents[ch][(i << bsize) >> esize];
1537                    let coef1 = self.coefs1[ch][i];
1538                    self.coefs[ch][coefs_pos] = coef1 * exp * mult;
1539                    coefs_pos += 1;
1540                }
1541                let tail = self.block_len - self.coefs_end[bsize];
1542                for _ in 0..tail {
1543                    self.coefs[ch][coefs_pos] = 0.0;
1544                    coefs_pos += 1;
1545                }
1546            }
1547        }
1548
1549        if self.ms_stereo && self.channel_coded[1] {
1550            if !self.channel_coded[0] {
1551                for v in &mut self.coefs[0][..self.block_len] {
1552                    *v = 0.0;
1553                }
1554                self.channel_coded[0] = true;
1555            }
1556            let (c0, c1) = self.coefs.split_at_mut(1);
1557            let v0 = &mut c0[0][..self.block_len];
1558            let v1 = &mut c1[0][..self.block_len];
1559            butterflies_float(v0, v1);
1560        }
1561
1562        self.wma_decode_block_next(gb, bsize)
1563    }
1564
1565    fn wma_decode_block_next(&mut self, _gb: &mut GetBitContext<'_>, bsize: usize) -> Result<bool> {
1566        // MDCT + window add.
1567        for ch in 0..self.channels {
1568            let n4 = self.block_len / 2;
1569            if self.channel_coded[ch] {
1570                self.mdct[bsize].imdct_full(
1571                    &mut self.output[..self.block_len * 2],
1572                    &self.coefs[ch][..self.block_len],
1573                );
1574            } else if !(self.ms_stereo && ch == 1) {
1575                for v in &mut self.output[..self.block_len * 2] {
1576                    *v = 0.0;
1577                }
1578            }
1579
1580            let index = (self.frame_len / 2) + self.block_pos - n4;
1581            // frame_out has length 2*BLOCK_MAX_SIZE.
1582            let frame_len_bits = self.frame_len_bits;
1583            let block_len_bits = self.block_len_bits;
1584            let prev_block_len_bits = self.prev_block_len_bits;
1585            let next_block_len_bits = self.next_block_len_bits;
1586            let block_len = self.block_len;
1587            let windows = &self.windows;
1588            let output = &self.output;
1589            let out_slice = &mut self.frame_out[ch][index..index + block_len * 2];
1590            wma_window_apply(
1591                out_slice,
1592                output,
1593                windows,
1594                frame_len_bits,
1595                block_len_bits,
1596                prev_block_len_bits,
1597                next_block_len_bits,
1598                block_len,
1599            );
1600        }
1601
1602        self.block_num += 1;
1603        self.block_pos += self.block_len;
1604        Ok(self.block_pos >= self.frame_len)
1605    }
1606
1607    fn wma_decode_frame(
1608        &mut self,
1609        gb: &mut GetBitContext<'_>,
1610        samples: &mut [Vec<f32>; MAX_CHANNELS],
1611        samples_offset: usize,
1612    ) -> Result<()> {
1613        self.block_num = 0;
1614        self.block_pos = 0;
1615        loop {
1616            let last = self.wma_decode_block(gb)?;
1617            if last {
1618                break;
1619            }
1620        }
1621
1622        for ch in 0..self.channels {
1623            samples[ch][samples_offset..samples_offset + self.frame_len]
1624                .copy_from_slice(&self.frame_out[ch][..self.frame_len]);
1625            // Shift for overlap.
1626            let tail = self.frame_out[ch][self.frame_len..self.frame_len * 2].to_vec();
1627            self.frame_out[ch][..self.frame_len].copy_from_slice(&tail);
1628        }
1629
1630        Ok(())
1631    }
1632}
1633
1634#[cfg(test)]
1635mod exponent_pow_tab_index_tests {
1636    use super::exponent_pow_tab_index;
1637
1638    #[test]
1639    fn accepts_full_ffmpeg_pow_tab_window() {
1640        assert_eq!(exponent_pow_tab_index(-60), Some(0));
1641        assert_eq!(exponent_pow_tab_index(-1), Some(59));
1642        assert_eq!(exponent_pow_tab_index(0), Some(60));
1643        assert_eq!(exponent_pow_tab_index(95), Some(155));
1644    }
1645
1646    #[test]
1647    fn rejects_exponents_outside_ffmpeg_pow_tab_window() {
1648        assert_eq!(exponent_pow_tab_index(-61), None);
1649        assert_eq!(exponent_pow_tab_index(96), None);
1650    }
1651}