/// Decodes all intensity stereo coded bands within an entire short block for MPEG2 and MPEG2.5
/// bitstreams, and returns the intensity bound.
Decodes all intensity stereo coded bands within an entire short block for MPEG2 and MPEG2.5
bitstreams, and returns the intensity bound.
Decodes all intensity stereo coded bands within an entire short block for MPEG2 and MPEG2 . 5 bitstreams and returns the intensity bound .
fn process_intensity_short_block_mpeg2(
    header: &FrameHeader,
    granule: &Granule,
    is_mixed: bool,
    mid_side: bool,
    ch0: &mut [f32; 576],
    ch1: &mut [f32; 576],
) -> usize {
    // Intensity stereo coding for short blocks in ISO/IEC 13818-3 is significantly more complex
    // than any other bitstream version.
    //
    // For short, non-mixed, blocks, each band is composed of 3 windows (windows 0 thru 2). Windows
    // are interleaved in each band.
    //
    // +--------------+--------------+--------------+-------+
    // |     sfb0     |     sfb1     |     sfb2     |  ...  |
    // +--------------+--------------+--------------+-------+
    // | w0 | w1 | w2 | w0 | w1 | w2 | w0 | w1 | w2 |  ...  |
    // +--------------+--------------+--------------+-------+
    //
    // However, each window of the same index is logically contiguous as depicted below.
    //
    // +------+------+------+------+
    // | sfb0 | sfb1 | sfb2 | .... |
    // +------+------+------+------+
    // |  w0  |  w0  |  w0  | .... |
    // +-------------+------+------+
    // |  w1  |  w1  |  w1  | .... |
    // +-------------+------+------+
    // |  w2  |  w2  |  w2  | .... |
    // +------+------+------+------+
    //
    // Unlike ISO/IEC 11172-3, where the intensity bound is a band boundary, each logically
    // contiguous window may have it's own intensity bound. For example, in the example below, the
    // intensity bound for window 0 is sfb0, for window 1 it's sfb2, and for window 2 it's sfb1.
    //
    //      +------+------+------+------+
    //      | sfb0 | sfb1 | sfb2 | .... |
    //      +------+------+------+------+
    //  w0  | 0000 | 0000 | 0000 | 0... |
    //      +-------------+------+------+
    //  w1  | abcd | xyzw | 0000 | 0... |
    //      +-------------+------+------+
    //  w2  | xyz0 | 0000 | 0000 | 0... |
    //      +------+------+------+------+
    //
    // For short blocks that are mixed, the long bands at the start follow the same rules as long
    // blocks (see above). For example, for the block below, if sfb1 is the intensity bound, then
    // all samples from sfb1 onwards must be zero. If the intensity bound is not within the long
    // bands then the rules stated above are followed whereby each window has it's own intensity
    // bound.
    //
    // |> Long bands        |> Short bands (3 windows)
    // +------+------+------+--------+--------+------+
    // | sfb0 | sfb1 | .... | sfbN-2 | sfbN-1 | sfbN |
    // |------+------+------+--------+--------+------+
    // |      |      |      |   w0   |   w0   |  w0  |
    // |      |      |      +--------+--------+------+
    // |      |      | .... |   w1   |   w1   |  w1  |
    // |      |      |      +--------+--------+------+
    // |      |      |      |   w2   |   w2   |  w2  |
    // +------+------+------+--------+--------+------+
    //
    // Regardless of the intensity bound, if a long band or short window is intensity stereo coded,
    // then it is decoded as per usual. If the long band or short window is not intensity stereo
    // coded, and mid-side stereo coding is enabled, then it should be mid-side stereo decoded.
    // This constant is the bit pattern 0b001 repeated 21 times over (63 bits total). When used as a
    // mask value, it retrieves every 3rd bit start from the least-significant bit.
    const WIN_MASK: u64 = 0x4924_9249_2492_4924;
    // If the short block is mixed, then use the mixed bands table, otherwise use the short band
    // table.
    let bands = if is_mixed {
        SFB_MIXED_BANDS[header.sample_rate_idx]
    }
    else {
        &SFB_SHORT_BANDS[header.sample_rate_idx]
    };
    // Retrieve the intensity stereo ratios table.
    let is_pos_table =
        &INTENSITY_STEREO_RATIOS_MPEG2[granule.channels[1].scalefac_compress as usize & 0x1];
    let rzero = max(granule.channels[0].rzero, granule.channels[1].rzero);
    // Build a bitmap where non-zero bands and/or windows are marked with a 1.
    let mut nz_map = 0u64;
    for (i, (start, end)) in bands.iter().zip(&bands[1..]).enumerate() {
        // Bands or windows starting at or beyond rzero are all 0 so there is no need to process
        // them.
        if *start >= rzero {
            break;
        }
        // Check if a band is non-zero, and if so, record it in the non-zero band map.
        if ch1[*start..*end].iter().find(|&&x| x != 0.0).is_some() {
            nz_map |= 0x1 << i;
        }
    }
    // If there is a set of contiguous non-zero bands and/or windows, these will never be intensity
    // stereo coded. They may be mid-side stereo encoded, however. Therefore, a conservative
    // estimate of the intensity bound is the end of the last non-zero band in this set.
    let is_bound = bits::trailing_ones_u64(nz_map) as usize;
    // Consume all bands before the intensity bound.
    nz_map >>= is_bound;
    // Create an iterator that yields a band start-end pair, and scale-factor.
    let bands_iter = bands.iter()
                          .zip(&bands[1..])
                          .zip(granule.channels[1].scalefacs.iter())
                          .skip(is_bound);
    // Iterate over each band and process it accordingly.
    for ((start, end), is_pos) in bands_iter {
        // Bands or windows starting at or beyond rzero are all 0 so there is no need to process
        // them.
        if *start >= rzero {
            break;
        }
        // This band only contains zeros. It *may* be intensity stereo coded if the remaining bands
        // and/or windows are all zero as well.
        let do_intensity = if nz_map & 1 == 0 {
            // If the block is mixed, and the sample index is < 36, then the current band is a long
            // band. A long band in a mixed block can only be intensity stereo coded if all the
            // remaining long and short bands are zero.
            if is_mixed && (*start < 36) {
                nz_map == 0
            }
            // Otherwise, the band is short (mixed block or otherwise). Short bands are composed of
            // 3 windows. If the corresponding windows in the remaining bands are also zero, then
            // this window is intensity stereo coded.
            else {
                nz_map & WIN_MASK == 0
            }
        }
        else {
            // If the band is non-zero then it is never intensity encoded.
            false
        };
        // If the band or window was coded with intensity stereo encoding then decode it now.
        if do_intensity {
            process_intensity_mpeg2(
                is_pos_table,
                *is_pos as usize,
                mid_side,
                &mut ch0[*start..*end],
                &mut ch1[*start..*end],
            );
        }
        // If intensity stereo coding was not used, but mid-side stereo coding is enabled, decode
        // the band or window's mid-side stereo coding.
        else if mid_side {
            process_mid_side(&mut ch0[*start..*end], &mut ch1[*start..*end]);
        }
        // Consume the bitmap. Shifting right lets us use the same window mask for all windows in a
        // band.
        nz_map >>= 1;
    }
    // Since short/mixed blocks can be sparse, mid-side stereo decoding is done on a band-by-band,
    // window-by-window basis in this case. So the intensity bound is 0.
    bands[is_bound]
}
fn process_intensity_short_block_mpeg2 ( header : & FrameHeader , granule : & Granule , is_mixed : bool , mid_side : bool , ch0 : & mut [ f32 ; 576 ] , ch1 : & mut [ f32 ; 576 ] , ) -> usize { // Intensity stereo coding for short blocks in ISO/IEC 13818-3 is significantly more complex // than any other bitstream version. // // For short, non-mixed, blocks, each band is composed of 3 windows (windows 0 thru 2). Windows // are interleaved in each band. // // +--------------+--------------+--------------+-------+ // |     sfb0     |     sfb1     |     sfb2     |  ...  | // +--------------+--------------+--------------+-------+ // | w0 | w1 | w2 | w0 | w1 | w2 | w0 | w1 | w2 |  ...  | // +--------------+--------------+--------------+-------+ // // However, each window of the same index is logically contiguous as depicted below. // // +------+------+------+------+ // | sfb0 | sfb1 | sfb2 | .... | // +------+------+------+------+ // |  w0  |  w0  |  w0  | .... | // +-------------+------+------+ // |  w1  |  w1  |  w1  | .... | // +-------------+------+------+ // |  w2  |  w2  |  w2  | .... | // +------+------+------+------+ // // Unlike ISO/IEC 11172-3, where the intensity bound is a band boundary, each logically // contiguous window may have it's own intensity bound. For example, in the example below, the // intensity bound for window 0 is sfb0, for window 1 it's sfb2, and for window 2 it's sfb1. // //      +------+------+------+------+ //      | sfb0 | sfb1 | sfb2 | .... | //      +------+------+------+------+ //  w0  | 0000 | 0000 | 0000 | 0... | //      +-------------+------+------+ //  w1  | abcd | xyzw | 0000 | 0... | //      +-------------+------+------+ //  w2  | xyz0 | 0000 | 0000 | 0... | //      +------+------+------+------+ // // For short blocks that are mixed, the long bands at the start follow the same rules as long // blocks (see above). For example, for the block below, if sfb1 is the intensity bound, then // all samples from sfb1 onwards must be zero. If the intensity bound is not within the long // bands then the rules stated above are followed whereby each window has it's own intensity // bound. // // |> Long bands        |> Short bands (3 windows) // +------+------+------+--------+--------+------+ // | sfb0 | sfb1 | .... | sfbN-2 | sfbN-1 | sfbN | // |------+------+------+--------+--------+------+ // |      |      |      |   w0   |   w0   |  w0  | // |      |      |      +--------+--------+------+ // |      |      | .... |   w1   |   w1   |  w1  | // |      |      |      +--------+--------+------+ // |      |      |      |   w2   |   w2   |  w2  | // +------+------+------+--------+--------+------+ // // Regardless of the intensity bound, if a long band or short window is intensity stereo coded, // then it is decoded as per usual. If the long band or short window is not intensity stereo // coded, and mid-side stereo coding is enabled, then it should be mid-side stereo decoded. // This constant is the bit pattern 0b001 repeated 21 times over (63 bits total). When used as a // mask value, it retrieves every 3rd bit start from the least-significant bit. const WIN_MASK : u64 = 0x4924_9249_2492_4924 ; // If the short block is mixed, then use the mixed bands table, otherwise use the short band // table. let bands = if is_mixed { SFB_MIXED_BANDS [ header . sample_rate_idx ] } else { & SFB_SHORT_BANDS [ header . sample_rate_idx ] } ; // Retrieve the intensity stereo ratios table. let is_pos_table = & INTENSITY_STEREO_RATIOS_MPEG2 [ granule . channels [ 1 ] . scalefac_compress as usize & 0x1 ] ; let rzero = max ( granule . channels [ 0 ] . rzero , granule . channels [ 1 ] . rzero ) ; // Build a bitmap where non-zero bands and/or windows are marked with a 1. let mut nz_map = 0u64 ; for ( i , ( start , end ) ) in bands . iter ( ) . zip ( & bands [ 1 .. ] ) . enumerate ( ) { // Bands or windows starting at or beyond rzero are all 0 so there is no need to process // them. if * start >= rzero { break ; } // Check if a band is non-zero, and if so, record it in the non-zero band map. if ch1 [ * start .. * end ] . iter ( ) . find ( | & & x | x != 0.0 ) . is_some ( ) { nz_map |= 0x1 << i ; } } // If there is a set of contiguous non-zero bands and/or windows, these will never be intensity // stereo coded. They may be mid-side stereo encoded, however. Therefore, a conservative // estimate of the intensity bound is the end of the last non-zero band in this set. let is_bound = bits :: trailing_ones_u64 ( nz_map ) as usize ; // Consume all bands before the intensity bound. nz_map >>= is_bound ; // Create an iterator that yields a band start-end pair, and scale-factor. let bands_iter = bands . iter ( ) . zip ( & bands [ 1 .. ] ) . zip ( granule . channels [ 1 ] . scalefacs . iter ( ) ) . skip ( is_bound ) ; // Iterate over each band and process it accordingly. for ( ( start , end ) , is_pos ) in bands_iter { // Bands or windows starting at or beyond rzero are all 0 so there is no need to process // them. if * start >= rzero { break ; } // This band only contains zeros. It *may* be intensity stereo coded if the remaining bands // and/or windows are all zero as well. let do_intensity = if nz_map & 1 == 0 { // If the block is mixed, and the sample index is < 36, then the current band is a long // band. A long band in a mixed block can only be intensity stereo coded if all the // remaining long and short bands are zero. if is_mixed && ( * start < 36 ) { nz_map == 0 } // Otherwise, the band is short (mixed block or otherwise). Short bands are composed of // 3 windows. If the corresponding windows in the remaining bands are also zero, then // this window is intensity stereo coded. else { nz_map & WIN_MASK == 0 } } else { // If the band is non-zero then it is never intensity encoded. false } ; // If the band or window was coded with intensity stereo encoding then decode it now. if do_intensity { process_intensity_mpeg2 ( is_pos_table , * is_pos as usize , mid_side , & mut ch0 [ * start .. * end ] , & mut ch1 [ * start .. * end ] , ) ; } // If intensity stereo coding was not used, but mid-side stereo coding is enabled, decode // the band or window's mid-side stereo coding. else if mid_side { process_mid_side ( & mut ch0 [ * start .. * end ] , & mut ch1 [ * start .. * end ] ) ; } // Consume the bitmap. Shifting right lets us use the same window mask for all windows in a // band. nz_map >>= 1 ; } // Since short/mixed blocks can be sparse, mid-side stereo decoding is done on a band-by-band, // window-by-window basis in this case. So the intensity bound is 0. bands [ is_bound ] }
Decodes all intensity stereo coded bands within an entire short block for MPEG2 and MPEG2.5
bitstreams, and returns the intensity bound.
Decodes all intensity stereo coded bands within an entire short block for MPEG2 and MPEG2 . 5 bitstreams and returns the intensity bound .
header
&FrameHeader
granule
&Granule
is_mixed
bool
mid_side
bool
ch0
&mut [f32; 576]
ch1
&mut [f32; 576]