Skip to content

post_decoder()->blend_subfr2(): Mismatch in subframe length

For the bitrate switching case, there is a blending of filter responses in post_decoder():

if ( pfstat_on_previous )
{
    /* Past frame was low-bitrate with formant post-filter */
    lsp2a_stab( st->lsp_old, A, M );
    mvr2r( st->hPFstat->mem_pf_in + L_SYN_MEM - M, synth - M, M );
    L_subfr = st->L_frame / st->nb_subfr;
    residu( A, M, synth, synth_buf, L_subfr );
    syn_filt( A, M, synth_buf, synth2, L_subfr, st->hPFstat->mem_stp + L_SYN_MEM - M, 0 );
    scale_st( synth, synth2, &st->hPFstat->gain_prec, L_subfr, -1 );
    blend_subfr2( synth2 + L_subfr / 2, synth + L_subfr / 2, synth2 + L_subfr / 2 );
}

So, when switching from a low-br mode to a high-br-mode, L_subfr is actually 128 samples (at 25.8 or 32.0 kHz). However, blend_subfr2() is internally hardcoded to a subframe length of 64 only (L_SUBFR).

void blend_subfr2(
    float *sigIn1,
    float *sigIn2,
    float *sigOut )
{
    float fac1 = 1.f - ( 1.f / L_SUBFR );
    float fac2 = 0.f + ( 1.f / L_SUBFR );
    float step = 1.f / ( L_SUBFR / 2 );
    int16_t i;

    for ( i = 0; i < L_SUBFR / 2; i++ )
    {
        sigOut[i] = fac1 * sigIn1[i] + fac2 * sigIn2[i];
        fac1 -= step;
        fac2 += step;
    }

    return;
}

Thus, we might get small discontinuities when calling it in this case.