/// Applies the anti-aliasing filter to sub-bands that are not part of short blocks.
Applies the anti-aliasing filter to sub-bands that are not part of short blocks.
Applies the anti - aliasing filter to sub - bands that are not part of short blocks .
pub(super) fn antialias(channel: &GranuleChannel, samples: &mut [f32; 576]) {
    // The number of sub-bands to anti-aliasing depends on block type.
    let sb_end = match channel.block_type {
        // Short blocks are never anti-aliased.
        BlockType::Short { is_mixed: false } => return,
        // Mixed blocks have a long block span the first 36 samples (2 sub-bands). Therefore, only
        // anti-alias these two sub-bands.
        BlockType::Short { is_mixed: true  } =>  2 * 18,
        // All other block types require all 32 sub-bands to be anti-aliased.
        _                                    => 32 * 18,
    };
    // Amortize the lazy_static fetch over the entire anti-aliasing operation.
    let (cs, ca): &([f32; 8], [f32; 8]) = &ANTIALIAS_CS_CA;
    // Anti-aliasing is performed using 8 butterfly calculations at the boundaries of ADJACENT
    // sub-bands. For each calculation, there are two samples: lower and upper. For each iteration,
    // the lower sample index advances backwards from the boundary, while the upper sample index
    // advances forward from the boundary.
    //
    // For example, let B(li, ui) represent the butterfly calculation where li and ui are the
    // indicies of the lower and upper samples respectively. If j is the index of the first sample
    // of a sub-band, then the iterations are as follows:
    //
    // B(j-1,j), B(j-2,j+1), B(j-3,j+2), B(j-4,j+3), B(j-5,j+4), B(j-6,j+5), B(j-7,j+6), B(j-8,j+7)
    //
    // The butterfly calculation itself can be illustrated as follows:
    //
    //              * cs[i]
    //   l0 -------o------(-)------> l1
    //               \    /                  l1 = l0 * cs[i] - u0 * ca[i]
    //                \  / * ca[i]           u1 = u0 * cs[i] + l0 * ca[i]
    //                 \
    //               /  \  * ca[i]           where:
    //             /     \                       cs[i], ca[i] are constant values for iteration i,
    //   u0 ------o------(+)-------> u1          derived from table B.9 of ISO/IEC 11172-3.
    //             * cs[i]
    //
    // Note that all butterfly calculations only involve two samples, and all iterations are
    // independant of each other. This lends itself well for SIMD processing.
    for sb in (18..sb_end).step_by(18) {
        for i in 0..8 {
            let li = sb - 1 - i;
            let ui = sb + i;
            let lower = samples[li];
            let upper = samples[ui];
            samples[li] = lower * cs[i] - upper * ca[i];
            samples[ui] = upper * cs[i] + lower * ca[i];
        }
    }
}
pub ( super ) fn antialias ( channel : & GranuleChannel , samples : & mut [ f32 ; 576 ] ) { // The number of sub-bands to anti-aliasing depends on block type. let sb_end = match channel . block_type { // Short blocks are never anti-aliased. BlockType :: Short { is_mixed : false } => return , // Mixed blocks have a long block span the first 36 samples (2 sub-bands). Therefore, only // anti-alias these two sub-bands. BlockType :: Short { is_mixed : true } => 2 * 18 , // All other block types require all 32 sub-bands to be anti-aliased. _ => 32 * 18 , } ; // Amortize the lazy_static fetch over the entire anti-aliasing operation. let ( cs , ca ) : & ( [ f32 ; 8 ] , [ f32 ; 8 ] ) = & ANTIALIAS_CS_CA ; // Anti-aliasing is performed using 8 butterfly calculations at the boundaries of ADJACENT // sub-bands. For each calculation, there are two samples: lower and upper. For each iteration, // the lower sample index advances backwards from the boundary, while the upper sample index // advances forward from the boundary. // // For example, let B(li, ui) represent the butterfly calculation where li and ui are the // indicies of the lower and upper samples respectively. If j is the index of the first sample // of a sub-band, then the iterations are as follows: // // B(j-1,j), B(j-2,j+1), B(j-3,j+2), B(j-4,j+3), B(j-5,j+4), B(j-6,j+5), B(j-7,j+6), B(j-8,j+7) // // The butterfly calculation itself can be illustrated as follows: // //              * cs[i] //   l0 -------o------(-)------> l1 //               \    /                  l1 = l0 * cs[i] - u0 * ca[i] //                \  / * ca[i]           u1 = u0 * cs[i] + l0 * ca[i] //                 \ //               /  \  * ca[i]           where: //             /     \                       cs[i], ca[i] are constant values for iteration i, //   u0 ------o------(+)-------> u1          derived from table B.9 of ISO/IEC 11172-3. //             * cs[i] // // Note that all butterfly calculations only involve two samples, and all iterations are // independant of each other. This lends itself well for SIMD processing. for sb in ( 18 .. sb_end ) . step_by ( 18 ) { for i in 0 .. 8 { let li = sb - 1 - i ; let ui = sb + i ; let lower = samples [ li ] ; let upper = samples [ ui ] ; samples [ li ] = lower * cs [ i ] - upper * ca [ i ] ; samples [ ui ] = upper * cs [ i ] + lower * ca [ i ] ; } } }
Applies the anti-aliasing filter to sub-bands that are not part of short blocks.
Applies the anti - aliasing filter to sub - bands that are not part of short blocks .
channel
&GranuleChannel
samples
&mut [f32; 576]