/// Performs hybrid synthesis (IMDCT and windowing).
Performs hybrid synthesis (IMDCT and windowing).
Performs hybrid synthesis ( IMDCT and windowing ) .
pub(super) fn hybrid_synthesis(
    channel: &GranuleChannel,
    overlap: &mut [[f32; 18]; 32],
    samples: &mut [f32; 576],
) {
    // Determine the number of sub-bands to process as long blocks. Short blocks process 0 sub-bands
    // as long blocks, mixed blocks process the first 2 sub-bands as long blocks, and all other
    // block types (long, start, end) process all 32 sub-bands as long blocks.
    let n_long_bands = match channel.block_type {
        BlockType::Short { is_mixed: false } =>  0,
        BlockType::Short { is_mixed: true  } =>  2,
        _                                    => 32,
    };
    // For sub-bands that are processed as long blocks, perform the 36-point IMDCT.
    if n_long_bands > 0 {
        let mut output = [0f32; 36];
        // Select the appropriate window given the block type.
        let window = match channel.block_type {
            BlockType::Start => &IMDCT_WINDOWS[1],
            BlockType::End   => &IMDCT_WINDOWS[3],
            _                => &IMDCT_WINDOWS[0],
        };
        // For each of the 32 sub-bands (18 samples each)...
        for sb in 0..n_long_bands {
            let start = 18 * sb;
            // Perform the 36-point on the entire sub-band.
            imdct36::imdct36(&samples[start..(start + 18)], &mut output);
            // Overlap the lower half of the IMDCT output (values 0..18) with the upper values of
            // the IMDCT (values 18..36) of the /previous/ iteration of the IMDCT. While doing this
            // also apply the window.
            for i in 0..18 {
                samples[start + i] = overlap[sb][i] + (output[i] * window[i]);
                overlap[sb][i] = output[18 + i] * window[18 + i];
            }
        }
    }
    // If there are any sub-bands remaining, process them as short blocks. For short blocks, the
    // 12-point IMDCT must be used on each window.
    if n_long_bands < 32 {
        // Select the short block window.
        let window = &IMDCT_WINDOWS[2];
        // For each of the remaining 32 sub-bands (18 samples each)...
        for sb in n_long_bands..32 {
            let start = 18 * sb;
            // Perform the 12-point IMDCT on each of the 3 short windows within the sub-band (6
            // samples each).
            let mut output = [0f32; 36];
            imdct12_win(&samples[start..(start + 18)], window, &mut output);
            // Overlap the lower half of the IMDCT output (values 0..18) with the upper values of
            // the IMDCT (values 18..36) of the /previous/ iteration of the IMDCT.
            for i in 0..18 {
                samples[start + i] = overlap[sb][i] + output[i];
                overlap[sb][i] = output[18 + i];
            }
        }
    }
}
pub ( super ) fn hybrid_synthesis ( channel : & GranuleChannel , overlap : & mut [ [ f32 ; 18 ] ; 32 ] , samples : & mut [ f32 ; 576 ] , ) { // Determine the number of sub-bands to process as long blocks. Short blocks process 0 sub-bands // as long blocks, mixed blocks process the first 2 sub-bands as long blocks, and all other // block types (long, start, end) process all 32 sub-bands as long blocks. let n_long_bands = match channel . block_type { BlockType :: Short { is_mixed : false } => 0 , BlockType :: Short { is_mixed : true } => 2 , _ => 32 , } ; // For sub-bands that are processed as long blocks, perform the 36-point IMDCT. if n_long_bands > 0 { let mut output = [ 0f32 ; 36 ] ; // Select the appropriate window given the block type. let window = match channel . block_type { BlockType :: Start => & IMDCT_WINDOWS [ 1 ] , BlockType :: End => & IMDCT_WINDOWS [ 3 ] , _ => & IMDCT_WINDOWS [ 0 ] , } ; // For each of the 32 sub-bands (18 samples each)... for sb in 0 .. n_long_bands { let start = 18 * sb ; // Perform the 36-point on the entire sub-band. imdct36 :: imdct36 ( & samples [ start .. ( start + 18 ) ] , & mut output ) ; // Overlap the lower half of the IMDCT output (values 0..18) with the upper values of // the IMDCT (values 18..36) of the /previous/ iteration of the IMDCT. While doing this // also apply the window. for i in 0 .. 18 { samples [ start + i ] = overlap [ sb ] [ i ] + ( output [ i ] * window [ i ] ) ; overlap [ sb ] [ i ] = output [ 18 + i ] * window [ 18 + i ] ; } } } // If there are any sub-bands remaining, process them as short blocks. For short blocks, the // 12-point IMDCT must be used on each window. if n_long_bands < 32 { // Select the short block window. let window = & IMDCT_WINDOWS [ 2 ] ; // For each of the remaining 32 sub-bands (18 samples each)... for sb in n_long_bands .. 32 { let start = 18 * sb ; // Perform the 12-point IMDCT on each of the 3 short windows within the sub-band (6 // samples each). let mut output = [ 0f32 ; 36 ] ; imdct12_win ( & samples [ start .. ( start + 18 ) ] , window , & mut output ) ; // Overlap the lower half of the IMDCT output (values 0..18) with the upper values of // the IMDCT (values 18..36) of the /previous/ iteration of the IMDCT. for i in 0 .. 18 { samples [ start + i ] = overlap [ sb ] [ i ] + output [ i ] ; overlap [ sb ] [ i ] = output [ 18 + i ] ; } } } }
Performs hybrid synthesis (IMDCT and windowing).
Performs hybrid synthesis ( IMDCT and windowing ) .
channel
&GranuleChannel
overlap
&mut [[f32; 18]; 32]
samples
&mut [f32; 576]