Skip to content

Wrong use of imult1616() in ACELP rescaling

Function imult1616() is used to compute a signal length in the ACELP decoder rescaling at https://forge.3gpp.org/rep/sa4/audio/ivas-basop/-/blob/main/lib_dec/acelp_core_dec_ivas_fx.c?ref_type=heads#L751:

    Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame,
                 imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE );

Note that HIBND_ACB_L_FAC = 5 /2 but imult1616() converts it to 2.

Thus for st->L_frame = 256

 imult1616( st->L_frame, HIBND_ACB_L_FAC ) returns 512

while it should be

 st->L_frame * HIBND_ACB_L_FAC returns 640

I guess the fix should consist of:

#ifdef FIX
    IF( EQ_16( L_frame, L_FRAME ) )
    {
        Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, 
                     L_FRAME * HIBND_ACB_L_FAC, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE );
    }
    ELSE
    {        
        Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, 
                     L_FRAME16k * 2, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE );
    }
#else
    Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, 
                 imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE );
#endif

or simply in

#ifdef FIX      
    Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame, 
                 L_FRAME32k, 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE );
#else
    Rescale_exc( st->hMusicPF->dct_post_old_exc_fx, exc_fx, bwe_exc_fx, st->hGSCDec->last_exc_dct_in_fx, st->L_frame,
                 imult1616( st->L_frame, HIBND_ACB_L_FAC ), 0, &( st->Q_exc ), st->Q_subfr, NULL, 0, INACTIVE );
#endif
Edited by vaclav